PHP
Server-Sent-Events

Server-Sent Eventsでtail -Fっぽいやつ

More than 1 year has passed since last update.

ブラウザへのPUSH実装を考え、WebSocketを調べていたら、その何倍も手軽に実装できるServer-Sent EventsというAPIがあるということで、tail -Fっぽく、ファイルが更新されたらブラウザに差分をPUSHするスクリプトを書いてみました。

https://developer.mozilla.org/ja/docs/Server-sent_events/Using_server-sent_events

まず、サーバ側。Mozillaのサンプルを参考に、冒頭でContent-Typeを宣言し、1秒毎にファイルの更新をチェックし、最終更新時間(filemtime)が変わっていれば、差分を
data: ファイルの差分
という形式で出力します。

test.php
<?php

header("Content-Type: text/event-stream\n\n");

$fname = "test.txt";
$ftime = "";
$ftime_old = "";
$contents = "";
$contents_old = "";

while (1) {
    $ftime = filemtime($fname);

    if( $ftime != $ftime_old ){
        $contents = file_get_contents($fname);
        echo 'data:  '.str_replace($contents_old,"",$contents)."\n\n";
        $contents_old = $contents;
    }

    $ftime_old = $ftime;
    clearstatcache();
    ob_end_flush();
    sleep(1);
}

次にブラウザ側。EventSourceオブジェクトを生成し、onmessageハンドラでサーバからPUSHされたデータを読み込み表示します。

index.html
<ul id="eventList"></ul>
<script>
    var eventList = document.getElementById("eventList");
    var evtSource = new EventSource("test.php");

    evtSource.onmessage = function(e) {
        var newElement = document.createElement("li");

        newElement.innerHTML = e.data;
        eventList.appendChild(newElement);
    }
</script>