SSE长连接循环脚本仅curl可用、浏览器超时失效的问题求助(涉及Apache、PHP8.2、HTTP/2)
SSE长连接循环脚本仅curl可用、浏览器超时失效的问题求助(涉及Apache、PHP8.2、HTTP/2)
各位大佬好,我最近碰到一个SSE相关的棘手问题,折腾好几天都没找到原因,来这里求助大家!
先说说背景:大概2017年的时候我写了一套PHP的SSE服务端脚本和对应的JS代码,当时用PHP5+HTTP/1协议,配合那个年代的Firefox浏览器完全正常运行。但现在升级到PHP8.2+HTTP/2之后,不管用Firefox 140 ESR还是最新版Chrome,这套代码都跑不起来了——连接总会在60秒后超时。
我甚至试过用最简的SSE示例,发现一个奇怪的现象:如果把脚本里的while循环去掉,JS端会每隔5秒主动发起一次请求,这明显违背了SSE的设计初衷啊!我理解的SSE应该是服务器主动决定何时推送数据,而不是客户端轮询。但带while循环的完整版本,用curl测试完全正常,一到浏览器就失效。
下面是我用的PHP脚本代码:
<?php header('Content-Type: text/event-stream'); header('Cache-Control: no-cache, no-transform'); header('X-Accel-Buffering: no'); header('Access-Control-Allow-Origin: *'); set_time_limit(0); @ini_set('zlib.output_compression', 0); @ob_implicit_flush(true); // Loop until the client close the stream while (true) { // Echo time $time = date('r'); echo "data: The server time is: {$time}\n\n"; // Flush buffer (force sending data to client) @ob_flush(); flush(); // Wait 2 seconds for the next message / event sleep(2); } ?>
后来在朋友提醒下补充测试了Apache的HTTP协议版本,结果更诡异:
- 切换到HTTP/1后,curl要等整整2分钟才开始返回数据(之前HTTP/2下curl是即时响应的),Firefox的表现和curl一致,也是延迟很久才收到数据;
- 切回HTTP/2后,curl依然正常工作,但浏览器还是会超时,完全收不到推送。
附HTTP/1下的curl测试输出:
export LC_ALL=C; date; curl https://XXX/sse.php Fri Jul 25 23:17:48 EEST 2025 <-- date invoked data: The server time is: Sat, 26 Jul 2025 00:19:18 +0300 <-- received after 1 minute and 30 seconds. data: The server time is: Sat, 26 Jul 2025 00:19:20 +0300 data: The server time is: Sat, 26 Jul 2025 00:19:22 +0300 ... total 58 lines of data: received.
HTTP/2下curl的协商日志:
curl -v URL * ALPN: curl offers h2,http/1.1 * ALPN: server accepted h2
我现在满脑子疑问:是浏览器的JS对SSE的处理逻辑变了?还是我漏了什么配置?难道浏览器没法和HTTP/2配合使用SSE长连接吗?
内容来源于stack exchange
相关产品推荐
相关产品推荐

