ホームページ >ウェブフロントエンド >jsチュートリアル >node.jsでサーバーセントイベントを使用する方法
コアポイント
サーバーの送信イベントの利点
Webは、リクエスト応答に基づいてHTTPメッセージに応答します。ブラウザはURL要求を発行し、サーバーはデータを返します。これにより、ブラウザは画像、CSS、JavaScriptなどをより多くのリクエストを行い、サーバーが応答する場合があります。サーバーはブラウザに積極的にメッセージを送信できないので、データが変更されたことをどのように示していますか?幸いなことに、サーバー送信イベント(SSE)を使用して、ライブニュースリリース、天気予報、株価などの機能を追加できます。
標準のWebテクノロジーを使用してリアルタイムのデータの更新を実現することは常に可能でした:
1990年代のWebは、フルページまたはフレーム/iframeを使用して更新されました。
サーバー送信イベント(SSE)により、サーバーはいつでもブラウザにデータをプッシュできます。
SSEはもともと2006年に実装され、すべての主要なブラウザでこの標準をサポートしています。 WebSocketsとしてはあまり知られていないかもしれませんが、サーバーはイベントを簡単に送信し、標準のHTTPを使用し、一元配置通信をサポートし、自動再接続を提供します。このチュートリアルは、サードパーティモジュールのないNode.jsコードの例を提供しますが、SSEはPHPを含む他のサーバー側の言語で使用できます。
サーバーの送信イベントのクイックスタート
次のデモでは、少なくとも3秒ごとにランダムな間隔でランダムな間隔でランダム数を出力するnode.js Webサーバーを実装しています。ここでnode.js SSEデモを見つけることができます。
このコードは、標準node.js HTTPおよびURLモジュールを使用してWebサーバーを作成し、URLを解析します。
サーバーは、 /ランダムパスに遭遇したときに着信URL要求をチェックし、反応します:
<code class="language-javascript">import http from "node:http"; import url from "node:url";</code>
<code class="language-javascript">const port = 8000; http.createServer(async (req, res) => { // 获取 URI 路径 const uri = url.parse(req.url).pathname; // 返回响应 switch (uri) { case "/random": sseStart(res); sseRandom(res); break; } }).listen(port); console.log(`server running: http://localhost:${port}\n\n`);</code>
別の関数は乱数を送信し、ランダムな間隔が通過した後にそれ自体を呼び出します:
<code class="language-javascript">// SSE 头 function sseStart(res) { res.writeHead(200, { Content-Type: "text/event-stream", Cache-Control: "no-cache", Connection: "keep-alive" }); }</code>
コードをローカルに実行する場合、端末でCurlを使用して応答をテストできます。
<code class="language-javascript">// SSE 随机数 function sseRandom(res) { res.write("data: " + (Math.floor(Math.random() * 1000) + 1) + "\n\n"); setTimeout(() => sseRandom(res), Math.random() * 3000); }</code>ctrl
|を押します。
<code class="language-bash">$> curl -H Accept:text/event-stream http://localhost:8000/random data: 481 data: 127 data: 975</code>ブラウザのクライアントJavaScriptは、EventSourceオブジェクトコンストラクターを使用して /ランダムURIに接続します:
入力データは、メッセージイベントハンドラーをトリガーします。ここで、データ:文字列はイベントオブジェクトの.dataプロパティで使用可能です: 重要なヒント
fetch()と同様に、ブラウザは標準のHTTPリクエストを発行するため、CSP、CORSを処理し、2番目の
パラメーターをEventSourceコンストラクターに渡してCookieを送信する必要がある場合があります。<code class="language-javascript">// 客户端 JS const source = new EventSource("/random");</code>
サーバーは、接続された各ユーザーがデータを送信するために個別のRES応答オブジェクトを保持する必要があります。これは、次の呼び出しのために値を閉鎖に渡すことにより、上記のコードで達成されます。
<code class="language-javascript">source.addEventListener('message', e => { console.log('RECEIVED', e.data); });</code>メッセージデータは、形式データの文字列のみになります:
{ withCredentials: true }
SSEは上記よりも多くのコードを必要としませんが、次のセクションでは他のオプションについて説明します。
サーバーは、任意の数のSSEチャネルURLを提供できます。たとえば、
これは、単一ページにトピックが表示されている場合は実用的かもしれませんが、単一のページにニュース、天候、株価が表示されている場合はそうではありません。この場合、サーバーは各ユーザーの3つの接続を維持する必要があります。これにより、トラフィックが増加するとメモリの問題が発生する可能性があります。
別のオプションは、1つの通信チャネルにデータ型を送信する /最新 /最新などの単一のエンドポイントURLを提供することです。ブラウザは、 /最新の?type = news、weather、stockpriceなどのURLクエリ文字列に関心のあるトピックを示すことができます。これにより、サーバーは特定のメッセージに対するSSE応答を制限できます。
行の上に渡される関連event:
を持つことができます。
data:
<code class="language-javascript">import http from "node:http"; import url from "node:url";</code>
データ識別子を使用して
<code class="language-javascript">const port = 8000; http.createServer(async (req, res) => { // 获取 URI 路径 const uri = url.parse(req.url).pathname; // 返回响应 switch (uri) { case "/random": sseStart(res); sseRandom(res); break; } }).listen(port); console.log(`server running: http://localhost:${port}\n\n`);</code>
:data:
の後に送信することもできます。
id:
<code class="language-javascript">// SSE 头 function sseStart(res) { res.writeHead(200, { Content-Type: "text/event-stream", Cache-Control: "no-cache", Connection: "keep-alive" }); }</code>
最新のIDは、クライアントのイベントオブジェクトの.lasteventidプロパティでも利用できます。
retry遅延を指定
<code class="language-javascript">// SSE 随机数 function sseRandom(res) { res.write("data: " + (Math.floor(Math.random() * 1000) + 1) + "\n\n"); setTimeout(() => sseRandom(res), Math.random() * 3000); }</code>再接続は自動ですが、サーバーは特定の期間に新しいデータが必要ないことを知っている可能性があるため、アクティブな通信チャネルを保持する必要はありません。サーバーは、ミリ秒の値を含む最終メッセージの一部として、それ自体に
retry:
それを受信した後、ブラウザはSSE接続を放棄し、遅延時間が経過した後に再接続しようとします。
<code class="language-bash">$> curl -H Accept:text/event-stream http://localhost:8000/random data: 481 data: 127 data: 975</code>その他のイベントハンドラー
「メッセージ」と名前付きイベントに加えて、クライアントJavaScriptに「オープン」ハンドラーと「エラー」ハンドラーを作成することもできます。
サーバー接続が失敗または終了すると、「エラー」イベントがトリガーされます。イベントオブジェクトの.EventPhaseプロパティを確認して、何が起こっているのかを確認できます。
覚えておいてください、再接続する必要はありません:
<code class="language-javascript">// 客户端 JS const source = new EventSource("/random");</code>それは自動的に発生します。
SSE通信を終了します
<code class="language-javascript">source.addEventListener('message', e => { console.log('RECEIVED', e.data); });</code>
ブラウザは、eventsourceオブジェクトの.close()メソッドを使用してSSE通信を終了できます。たとえば、
サーバーは、次のように接続を終了できますretry:
遅延を送信してからのみのブラウザのみが、新しいEventSourceオブジェクトを作成することで接続を再確立できます。
結論
サーバー側のイベントは、リアルタイムページの更新を実装する方法を提供します。これは、Fetch()ベースのAJAXポーリングよりも簡単で実用的で軽量です。複雑さはサーバー側にあります。あなたがする必要があります:
唯一の欠点は、SSEでブラウザからメッセージをサーバーに送信できないことです(初期接続要求を除く)。 Ajaxを使用できますが、これはアクションゲームなどのアプリケーションには遅すぎます。適切な双方向通信には、WebSocketが必要です。詳細については、node.jsでWebSocketsを使用してライブアプリケーションを作成する方法をご覧ください!
以上がnode.jsでサーバーセントイベントを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。