【JavaScript, PHP】Server-Sent Events でプッシュ通信をする

JavaScriptとPHPでプッシュ通信をしてみます。

SSEとはServer-Sent Eventsの略でW3Cで提案されているhtml5関連APIの一種です。

これはサーバとの通信やJavaScript APIを中心としたもので、サーバからPush通信を行うための仕様です。

サーバからPush通信に関してはこれまでもCometやWebSocketが存在しましたが、SSEは互換性や効率などの点でそれ以外の技術に対する特徴があります。

Server Sent Events(SSE)の使いどころと使い方

Server Sent Eventsの詳細や注意点は上記のサイトがとても参考になります。以下は簡単なメモです。

JavaScript

$(function(){

    // 利用可能か
    if (window.EventSource) {

        // サーバに接続
        var es = new EventSource('sse.php');

        // メッセージを受信した場合
        es.addEventListener('message', function(e) {

            // id:
            console.log(e.lastEventId);

            // event: (デフォルトは message)
            console.log(e.type);

            console.log(e.origin);

            // JSONを受け取る場合は、parseする
            var data = JSON.parse(e.data);
            console.log(data.num);
        }, false);


        // サーバサイドで 任意のイベントを設定した場合
        es.addEventListener('close', function(e) {
            es.close();
        }, false);


        // エラー処理
        es.addEventListener('error', function(e) {

            // e.redyState
            // 0 接続試行中、再接続中
            // 1 接続中
            // 2 未接続、接続終了

            if (e.redyState !== 1) {
                // 終了
                es.close();
            }
        }, false);
    } else {
        alert('対応していません。');
    }
});

PHP

header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");

$n = 1;
while (1) {

    // 接続が中断された場合、再接続を開始するまでの時間をミリ秒で設定
    echo "retry: 3000\n";

    // e.lastEventIdとしてメイン処理へ渡される
    echo "id: $n\n";

    // e.typeとしてメイン処理へ渡される。デフォルトは message
    echo "event: message\n";

    // 文字列やJSON
    printf('data: {"num": "%d"}', rand(1, 6));

    // 空行で区切る
    echo "\n\n";

    // 別イベントの設定
    if ($n === 10) {
        echo "event: close\n";
        echo "data: finish\n\n";
    }

    // 出力
    ob_flush();
    flush();

    sleep(1);

    $n++;
}