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;如果输出是分块的,它将被设置。