文章转载自:

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);
})
分类: PHP 标签: SSE

评论

暂无评论数据

暂无评论数据

目录