実行し続けるにはある種のループが必要なため、スクリプトは出力を 1 回だけ表示します (もちろん、条件付きで実行しないと、何百万ものインスタンスが実行されます!!)。
これを実証するために今日以前に書いた実装を切り刻み、ストリームをより適切に管理するためにいくつかの追加の javascript/jquery を追加しました。以下は、Xampp (ローカル開発用) のようなシングル スレッドの PHP インストールでも機能します。ajax を使用して PHP を呼び出す場合は、beforesend で stream_close() を呼び出し、成功のコールバックで stream_open() を呼び出します。
以下はテストされていませんが、主に動作中のコードから取得されているため、問題ないはずです。
<?
//stream.php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
stream();
function stream(){
$data = array();
//collect data from database or wherever to stream to browser
//example data
$data[0]["name"] = 'Bob';
$data[0]["total"] = rand(0,100);
$data[0]["name"] = 'Jane';
$data[0]["total"] = rand(0,100);
//maybe there is no new data so just send one new line
//this is required to check if the connection is still alive
if(!empty($data)){
echo "\n";
}else{ //Otherwise json encode the data for output
echo 'data: '.json_encode($data)."\n\n";
}
flush(); //Flush the result to the browser
sleep(1); //Wait a second (or what ever you like)
//If the browser is still connected
if(!connection_aborted() && connection_status()==0){
stream(); //recurse the function
}
}
?>
<script>
var webstream = false;
function stream_open(){
stream_close(); //Close the stream it (in case we got here weirdly)
if(!!window.EventSource){ //Test compatibility
webstream = new EventSource('./stream.php');
console.log("Stream Opened"); //Log event for testing
webstream.addEventListener('message', function(e){
var data = JSON.parse(e.data); //Parse the json into an object
process_stream(data);
},false);
//Cleanup after navigating away (optional)
$(window).bind('beforeunload', function(){
webstream.onclose = function(){}; //delete onclose (optional)
webstream.close(); //Close the stream
});
}
}
function stream_close(){
if(typeof(webstream)=="object"){
webstream.close();
webstream = false;
console.log("Stream Closed"); //Log event for testing
}
}
function process_stream(data){
//do something with the new data from the stream, e.g. log in console
console.log(data);
}
//Optional:
//Toggle stream on blur/focus
//Good if the user opens multiple windows or Xampp?
$(window).on("blur focus", function(e) {
//get the last blur/focus event type
var prevType = $(this).data("prevType") || null;
if (prevType != e.type){
console.log(e.type); //Log event for testing (focus/blur)
switch (e.type){
case "blur":
stream_close(); //Close stream on blur
break;
case "focus":
stream_open(); //Open stream on focus
break;
}
}
//Store the last event type to data
$(this).data("prevType", e.type);
});
// Optional:
// Using idletimer plugin to close the stream in times of inactivity
// https://github.com/thorst/jquery-idletimer/blob/master/src/idle-timer.js
$(document).on("idle.idleTimer", function (){
stream_close();
});
$(document).on("active.idleTimer", function (){
stream_open();
});
$(document).idleTimer({timeout:5000}); //5 second idle timer
</script>