LMLPHP后院

基于 HTML5 的 EventSource 实时推送实现技术

maybe yes 发表于 2017-08-21 18:03

本文介绍 Comet 的 EventSource 实现方式,EventSource 对象只是对数据格式进行了简单的封装。服务端加上 event-stream 的头声明数据以事件流的方式传递,保持长连接

先上代码吧,后端代码示例 chat.php

0123456789101112131415161718192021222324252627282930
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 命令导致程序运行一直不成功,实在是个坑。

前端代码实现 comet.php

0123456789101112
<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 分钟重新请求一次,稳定性不错,连续几天不下线都能保持连接。

相关文章
2025-05-14 19:23:45 1747221825 0.033935