用thinkphp实现SSE(Server-sent Events)
文章转载自:
https://blog.csdn.net/sbchei/article/details/129871181
上面有详细的解释及问题处理,下面简要说明,以备日后使用
php代码:
public function stream() {
// 检查当前缓冲区级别
if (ob_get_level() > 0) {
// 如果有缓冲区,则清空缓冲区
ob_end_clean();
}
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
// 重点,必须要加
header('X-Accel-Buffering: no');
// 建立连接后,您可以输出初始化数据到客户端
echo "event: sse_init\ndata: {}\n\n";
flush();
// 监听事件源,并输出实时事件
while (true) {
$event = 'my_event';
// 获取要发送的事件数据
$data = 'Hello SSE!';
// 输出事件到客户端
echo "event: $event\ndata: $data\n\n";
flush();
// 休眠一段时间等待下次事件
sleep(1);
}
}
代码解释:
一开始的ob_end_clean()方法是清除之前的缓冲区域,使设置的返回头header('Content-Type: text/event-stream');生效,不然还会返回text/html格式,最终导致报错;
然后设置请求头,其他都好理解,重点是这句header('X-Accel-Buffering: no');,这段代码是强制关闭Nginx的代理缓存,其实也是关闭缓冲区域,不加这句话就会出现事件流最后一次性输出的问题;
然后就是使用echo+flush()方法向外输出事件流了,每次echo后面都要加上flush(),强制输出事件流;
最后还有个大坑,不要用Apache,要用Nginx,似乎是因为Apache对flush()方法支持有问题,无论怎么搞,最终还是一次性输出事件流;
js代码:
var source = new EventSource("<?php echo url('stream'); ?>");
source.addEventListener('my_event', function(event) {
console.log(event.data);
})
版权申明
本文系作者 @Mr.Yang 原创发布在果皮皮站点。未经许可,禁止转载。
暂无评论数据