Server-Sent Eventsとは、サーバー側で何らかの出来事が起きたことを、リアルタイムでクライアント側に知らせることを可能にする技術です。

一般的なウェブサーバーとの通信では、クライアントは問い合わせ(リクエスト)を送ってはじめて、サーバー側の状態を知ることができます。そのため、サーバー側の状態の変化をリアルタイムで知るには、通常は一定の間隔でリクエストを何度も送る必要があります。

しかし、この方法では、頻繁な再接続による負荷は避けられません。加えて、再接続のたびにユーザーの操作がクリアされないようにする配慮も必要になってきます。

Server-Sent Eventsの仕組み

Server-Sent Eventsでは、イベントをリアルタイムで伝達するための専用のテキストデータによる通信(イベントストリーム)を、ブラウザのバックグラウンドでサーバーとクライアントの間に開きます。

このイベントストリームは、実体はテキスト形式の通常のHTTPレスポンスですが、リクエストに対してすぐに完了せず、開かれたままの状態で必要なだけ維持され、サーバでイベントが起きる都度に随時、そのデータが追記されていきます。

サーバーが、データを分割して送信することを示すHTTPの「Transfer-Encoding: chunked」形式でイベントストリームを送った場合、このデータはクライアントにリアルタイムで順次送られ、クライアント側での解析も、接続が閉じられるのを待たず順次リアルタイムで行われます。

そうでない場合は、いったんレスポンスが閉じられた時点で、クライアント側でまとめて処理されます。

イベントストリームが閉じられると、クライアントは自動的に再接続を行い、イベントストリームを再開させます。

こうして、サーバー側で起きたイベントが記述されたテキストデータを、クライアントの背後で専用のオブジェクトが並行して継続的に受け取り続けることで、サーバー側のイベントのリアルタイムでの受け取りが可能になります。

この問題に対処するため、HTML5では、WebSocketとServer-Sent Eventsの二つの規格が追加されました。WebSocketと異なり、Server-Sent Eventsは通常のHTTPプロトコル上で動作し、サーバ側ではウェブアプリケーションのレベルで実装することが可能になっています。

動作テスト

PHP側のサンプルです。JS側はブラウザのソースを見るで見てください。
<?php
        set_time_limit(0);
        header("Content-Type: text/event-stream");
        header('Cache-Control: no-cache');
        $i = rand(0,9);
        echo "data: サーバ側の出力:$i\n\n";
        echo "retry: 3000";