EventSource

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.

EventSource インターフェイスは、サーバー送信イベントのウェブコンテンツのインターフェイスです。

EventSource インターフェイスは、 HTTP サーバーとの間で永続的なコネクションを開き、イベントtext/event-stream の形式で受け取ります。コネクションは EventSource.close() を呼び出して閉じられるまで開いたままになります。

EventTarget EventSource

コネクションが開かれた後、サーバーからの着信メッセージは、イベントという形式でコードに配信されます。着信メッセージにイベントフィールドがある場合、発生するイベント は、イベントフィールドの値と同じになります。イベントフィールドが存在しない場合、一般的な message イベントが発行されます。

WebSocket とは異なり、サーバー送信イベントは単一方向です。つまり、データメッセージはサーバーからクライアント(ユーザーのウェブブラウザーなど)に向けて、一方向に配信されます。これは、メッセージの形でクライアントからサーバーにデータを送る必要がない場合には良い選択です。例えば、 EventSource はソーシャルメディアの近況アップデートやニュースフィードのようなものを扱ったり、クライアント側ストレージIndexedDBweb storage など)の仕組みにデータを配信したりするアプローチに有用です。

警告: HTTP/2 上で使用されていない場合、 SSE は開いている接続の最大数に制限を受けます。この制限はブラウザーごとにあり、とても低い数 (6) に設定されているため、さまざまなタブを開くために特別な痛みを伴うことがあります。この問題は、ChromeFirefox で「修正予定なし」と表示されています。この制限はブラウザー+ドメインごとなので、 www.example1.com への SSE 接続をすべてのタブで 6 つ、www.example2.com. への SSE 接続をさらに 6 つ開くことができることを意味しています(Stackoverflow より)。 HTTP/2 を使用している場合、同時の HTTP ストリーム の最大数はサーバーとクライアントの間で交渉されます(既定値は 100)。

コンストラクター

EventSource()

指定した URL からサーバーが(オプションで資格情報モードで)送信するイベントを処理するための EventSource を新規に作成します。

インスタンスプロパティ

このインターフェイスは、親である EventTarget からプロパティを継承しています。

EventSource.readyState 読取専用

数値で、コネクションの状態を表します。取りうる値は CONNECTING (0)、OPEN (1)、CLOSED (2) です。

EventSource.url 読取専用

文字列で、ソースの URL を表します。

EventSource.withCredentials 読取専用

論理値で、 EventSource オブジェクトがオリジン間 (CORS) 資格情報を設定してインスタンス化されたか (true)、設定されずにインスタンス化されたか (false、既定値) を示します。

メソッド

このインターフェイスは、親である EventTarget からメソッドを継承しています。

EventSource.close()

コネクションを切断して、 readyState 属性を CLOSED に設定します。すでに切断されている場合は何も行いません。

イベント

error

イベントソースへのコネクションを開くことに失敗したときに発生します。

message

イベントソースからデータを受信したときに発生します。

open

イベントソースへのコネクションが開かれたときに発生します。

さらに、イベントソース自身がイベントフィールドを持つメッセージを送信し、その値をキーにしたアドホックイベントを作成することもできます。

この基本的な例では、 EventSource を生成してサーバーからイベントを受け取ります。 sse.php という名前のページがイベントを生成する責任を負います。

js
const evtSource = new EventSource("sse.php");
const eventList = document.querySelector("ul");

evtSource.onmessage = (e) => {
  const newElement = document.createElement("li");

  newElement.textContent = `message: ${e.data}`;
  eventList.appendChild(newElement);
};

受信されたそれぞれのイベントは、 EventSource オブジェクトの onmessage イベントハンドラーを実行させます。ここでは、新しい <li> 要素を生成してその中にメッセージのデータを書き込み、この要素を文書の中にある既存のリスト要素に追加します。

メモ: この例の全容が GitHub にあります。Simple SSE demo using PHP をご覧ください。

名前付きのイベントを待ち受けするには、送信されるイベントの種類ごとにリスナーが必要になります。

js
const sse = new EventSource("/api/v1/sse");

/*
 * これは以下のようなイベントのみを待ち受けします。
 *
 * event: notice
 * data: useful data
 * id: someid
 */
sse.addEventListener("notice", (e) => {
  console.log(e.data);
});

/*
 * 同様に、これは `event: update` というフィールドを持つ
 * イベントを待ち受けます。
 */
sse.addEventListener("update", (e) => {
  console.log(e.data);
});

/*
 * "message" というイベントは特別なケースで、
 * イベントフィールドを持たないイベントや、特定の型である
 * `event: message` を持つイベントを捕捉します。それは、
 * 他のイベント型では発生しません。
 */
sse.addEventListener("message", (e) => {
  console.log(e.data);
});

仕様書

Specification
HTML Standard
# the-eventsource-interface

ブラウザーの互換性

BCD tables only load in the browser

関連情報