SSE 在脚本执行完成之前不发送事件?
SSE not sending events until the script has finished executing?
我遇到一个问题,SSE 事件一直等到脚本执行完毕才最终发送数据,经过数小时的搜索合理的解释或解决方案后,我一无所获。
我找到了一个在那个网站上运行的示例,但是将该代码放到我的服务器上,它不起作用。 (URL: http://www.binarytides.com/monitor-progress-long-running-php-scripts-html5-server-sent-events/)
在这个例子中,我注意到 Transfer-Encoding: chunked
的 header 当我试图让 Apache 通过带有 Header set
的 .htaccess 发送这个 header 时,响应代码转向“(失败)”。
我还注意到该示例没有 Content-Length
,而我的服务器中有。
这一切都在 Chrome v.53.0.2785.116m
上进行了测试
在那之后我决定把它放到书架上。
这是一个例子:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
function sendMsg($id, $msg) {
echo "id: $id" . PHP_EOL;
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
while ($x < 5) {
$serverTime = time();
sendMsg($serverTime, 'server time: ' . date("h:i:s", time()));
sleep(1);
$x++;
}
?>
如果我要对这个脚本执行请求,我会得到这些 headers:
HTTP/1.1 200 OK
Date: Tue, 27 Sep 2016 22:34:11 GMT
Server: Apache
Cache-Control: no-cache
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 91
Keep-Alive: timeout=15, max=43
Connection: Keep-Alive
Content-Type: text/event-stream
在脚本完成执行之前,我不会从中获取任何数据。
此时我不清楚是它的 Apache 还是 PHP 出了问题,但据我所知是服务器出了问题。
我试过 PHP 的版本,从 5.5-7 不等,都没有运气。
关于这里出了什么问题以及如何解决它有什么想法吗?
编辑 1:
我在另一台服务器上尝试了相同的脚本并且它工作正常,并发送了以下 headers:
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 28 Sep 2016 15:40:00 GMT
Content-Type: text/event-stream;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=15
Cache-Control: no-cache
ngpass_ngall: 1
我怀疑问题是 gzip-ing 输出。 (您的工作 nginx 服务器没有这样做。)
在你的 .htaccess 文件中,你能试试这两个吗:
php_flag zlib.output_compression off
SetEnv no-gzip 1
(借自 https://webmasters.stackexchange.com/q/61258/18151 及其答案。)
顺便说一句,您不需要自己添加分块 header;如果输出是分块的,它将被设置。
我遇到一个问题,SSE 事件一直等到脚本执行完毕才最终发送数据,经过数小时的搜索合理的解释或解决方案后,我一无所获。
我找到了一个在那个网站上运行的示例,但是将该代码放到我的服务器上,它不起作用。 (URL: http://www.binarytides.com/monitor-progress-long-running-php-scripts-html5-server-sent-events/)
在这个例子中,我注意到 Transfer-Encoding: chunked
的 header 当我试图让 Apache 通过带有 Header set
的 .htaccess 发送这个 header 时,响应代码转向“(失败)”。
我还注意到该示例没有 Content-Length
,而我的服务器中有。
这一切都在 Chrome v.53.0.2785.116m
上进行了测试在那之后我决定把它放到书架上。
这是一个例子:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
function sendMsg($id, $msg) {
echo "id: $id" . PHP_EOL;
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
while ($x < 5) {
$serverTime = time();
sendMsg($serverTime, 'server time: ' . date("h:i:s", time()));
sleep(1);
$x++;
}
?>
如果我要对这个脚本执行请求,我会得到这些 headers:
HTTP/1.1 200 OK Date: Tue, 27 Sep 2016 22:34:11 GMT Server: Apache Cache-Control: no-cache Vary: Accept-Encoding,User-Agent Content-Encoding: gzip Content-Length: 91 Keep-Alive: timeout=15, max=43 Connection: Keep-Alive Content-Type: text/event-stream
在脚本完成执行之前,我不会从中获取任何数据。
此时我不清楚是它的 Apache 还是 PHP 出了问题,但据我所知是服务器出了问题。 我试过 PHP 的版本,从 5.5-7 不等,都没有运气。
关于这里出了什么问题以及如何解决它有什么想法吗?
编辑 1: 我在另一台服务器上尝试了相同的脚本并且它工作正常,并发送了以下 headers:
HTTP/1.1 200 OK Server: nginx Date: Wed, 28 Sep 2016 15:40:00 GMT Content-Type: text/event-stream;charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Keep-Alive: timeout=15 Cache-Control: no-cache ngpass_ngall: 1
我怀疑问题是 gzip-ing 输出。 (您的工作 nginx 服务器没有这样做。)
在你的 .htaccess 文件中,你能试试这两个吗:
php_flag zlib.output_compression off
SetEnv no-gzip 1
(借自 https://webmasters.stackexchange.com/q/61258/18151 及其答案。)
顺便说一句,您不需要自己添加分块 header;如果输出是分块的,它将被设置。