Server-sent events (SSE / サーバー送信イベント)

サーバーからウェブページにメッセージをプッシュ (push) することで、新しいデータをウェブページに送信できるようになります。

EventSource

サーバー側

サーバー側ではContent-Typeをtext/event-streamとします。メッセージのデータは"data"で指定し、末尾は"\n\n"とします。

たとえばPHPならば、次のようにします。

<?php
header('Content-Type: text/event-stream'); // SSEであることを、Content-Typeで表す
header('Cache-Control: no-cache');
header('X-Accel-Buffering: no');

do {
    $data = rand(0, 99);

    echo "data: {$data}"; // メッセージのデータ フィールド
    echo "\n\n";

    if (ob_get_contents()) ob_flush();
    flush();

    sleep(1);
} while (!connection_aborted()); // クライアントとの接続が切断されているならば、ループを抜ける
サーバーからのイベントの送信 - サーバー送信イベントの使用 - Web API | MDN

カスタムイベント

イベントの種類を指定するには"event"で、たとえばそれを"test"とするには

echo "event: test\n";
echo "data: {$data}";
echo "\n\n";

とします。

クライアント側

EventSourceで処理できます。EventSource - Web API | MDN

const url = 'sse.php'; // リモート リソースの場所
const eventSource = new EventSource(url);

eventSource.onopen = (event) => {
    console.log('接続が開かれた');
};

eventSource.onmessage = (event) => {
    console.log('メッセージを受信した:', event.data);
};

eventSource.onerror = (event) => {
    console.error('エラーが発生した:', event);
};

接続が不要となったならば、EventSource.close()で閉じます。EventSource.close() - Web API | MDN

カスタムイベント

イベントの種類が明示されているならば、addEventListener()でその種類を指定して捕捉します。

eventSource.addEventListener('test', (event) => {
    console.log(event.data);
});
JavaScriptのドキュメントから検索