基于 HTML5 的 EventSource 实时推送实现技术
本文介绍 Comet 的 EventSource 实现方式,EventSource 对象只是对数据格式进行了简单的封装。服务端加上 event-stream 的头声明,数据以事件流的方式传递,保持长连接。
if (isset($_REQUEST['message'])) { file_put_contents('/tmp/message.txt', time() . '||data: ' . $_REQUEST['message'] . "\n", FILE_APPEND); echo $_REQUEST['message']; exit; } function output($v) { echo "data: {$v}\n\n"; ob_flush(); flush(); } header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); header("Content-Encoding: none"); header('X-Accel-Buffering: no'); $last = time(); for (;;) { // exec('tail -n 1 /tmp/message.txt', $data); $tempArr = file('/tmp/message.txt'); $arr = explode('||', end($tempArr)); if ($arr[0] <= $last){ sleep(1); continue; } $last = $arr[0]; output($arr[1]); sleep(1); }
一开始,读取文件最后一行内容,使用 tail 命令导致程序运行一直不成功,实在是个坑。
<div id="result"></div> <script> if (typeof(EventSource)!=="undefined") { var source=new EventSource("/chat.php"); source.onmessage = function(event) { document.getElementById("result").innerHTML=event.data + " "; }; }else{ document.getElementById("result").innerHTML="抱歉,您的浏览器不支持 server-sent 事件 ..."; } </script>
本文示例后端使用文件保存聊天记录,读取文件内容的更新返回给客户端,通过保持长连接和 chunked 传输实现实时通信。
经过长时间观察测试,EventSource 会每隔大约 5 分钟重新请求一次,稳定性不错,连续几天不下线都能保持连接。
相关文章
暂无