关于apache:php脚本的内容未刷新

Content of php script is not flushed

我有以下代码(它使用服务器端事件,但问题是刷新无法正常工作):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php

class Events {
    function __construct($fn, $options=array()) {
        $settings = array_merge(array(
            'headers' => array(
                'Content-Type' => 'text/event-stream',
                'Cache-Control' => 'no-cache',
                'Connection' => 'keep-alive'
            ),
            'retry' => 2000
        ), $options);
        foreach($settings['headers'] as $header => $value) {
            header("$header: $value");
        }
        $lastId = intval(isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? $_SERVER["HTTP_LAST_EVENT_ID"] : 0);
        echo":" . str_repeat("", 2048) ."\
"
;
        echo"retry:" . $settings['retry'] ."\
"
;
        $id = $lastId;
        $i = 0;
        foreach ($fn($id) as $value) {
            echo"id:" . $id++ ."\
"
;
            echo"data:" . $value ."\
\
"
;
            ob_flush();
            flush();
            if ($i++ == 10) {
                break;
            }
        }
    }
}
if (isset($_SERVER['HTTP_ACCEPT']) && preg_match("%text/event-stream%", $_SERVER['HTTP_ACCEPT'])) {

    new Events(function($id) {
        while(true) {
            $array = array("Foo","Bar","Baz","Quux");
            yield json_encode(array("message" => $array[array_rand($array)]));
            sleep(1);
        }
    });
} else { ?><!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    Leash
    <meta name="Description" content=""/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://code.jquery.com/jquery-3.1.1.min.js">
   
var source = new EventSource("/EventSource.php");
source.addEventListener("message", function(message) {
    console.log(JSON.parse(message.data).message);
});
   
    <body>
        <textarea></textarea>
    </body>
</html><?php } ?>

它在wamp服务器上本地工作,但不在我的共享主机上,我在php信息中有此信息:

1
2
3
4
Server API          CGI/FastCGI

Directive           Local Value    Master Value
output_buffering    4096           4096

并且我无法更改它,我尝试将ob_start()也添加到我的脚本中,同时ini_set('output_buffering', 0)并删除了ob_flush,但这无济于事。

我还尝试在.user.ini中将目录的output_buffering设置为0,并且php信息显示Local Value为0,但服务器端事件仍然不起作用,我一次获得了所有事件,开发人员工具说(pending)为空类型,直到10秒后完成。

Developer

我再次尝试运行代码(几年后,在Fedora / Linux上),但结果却相同。 Gzip尚未打开,但消息显示在末尾。

我尝试过:

  • 添加标题'X-Accel-Buffering' => 'no'
  • 还添加了echo"event:". $event ."\
    ";

未成功。

我正在查看使用while循环时未加载服务器端PHP事件页面,但解决方案无效,代码给出的错误与OP相同(他没有太多代表,因此他可能对SO不活跃) ),我至少显示了事件,但我打破了循环,他的代码有无限循环。

这是服务器(Fedora)发送的标头:

1
2
3
4
5
6
7
8
9
Cache-Control: no-cache
Connection: keep-alive, Keep-Alive
Content-Type: text/event-stream;charset=UTF-8
Date: Tue, 17 Sep 2019 07:40:44 GMT
Keep-Alive: timeout=5, max=92
Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1c
Transfer-Encoding: chunked
X-Accel-Buffering: no
X-Powered-By: PHP/7.2.22

在http://demo.howopensource.com/sse/

上的简单代码上也是如此

我的php.ini有这个:

1
2
3
$ grep -E 'user_ini|output_buffer|zlip.' /etc/php.ini | grep -v '^;'
user_ini.filename =".user.ini"
output_buffering = 4096

所以我也尝试过用

设置.user.init文件

1
output_buffering = 0

1
output_buffering = Off

但是它也不起作用。脚本正在等待立即返回所有内容。本文中的代码流PHP-禁用PHP,Apache,Nginx和Varnish中的输出缓冲如果我使用$string_length = 4096;,即使该phpinfo也说该目录的本地输出缓冲被禁用。

EDIT2:

它似乎冲洗功能可以在我的共享主机上运行,??https://jcubic.pl/01.php?size = 100,但由于冲洗功能不起作用,我无法在Fedora上对其进行本地测试。

这是我本地phpinfo输出的链接:https://jcubic.pl/phpinfo().html


我已经通过apache启用gzip压缩回答了这个问题,从而解决了该问题:

在.htaccess文件中禁用Gzip压缩