【问题标题】:Content of php script is not flushed未刷新 php 脚本的内容
【发布时间】:2016-12-03 18:14:26
【问题描述】:

我有这段代码(它使用服务器端事件,但问题是刷新不起作用):

<?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) . "\n";
        echo "retry: " . $settings['retry'] . "\n";
        $id = $lastId;
        $i = 0;
        foreach ($fn($id) as $value) {
            echo "id:" . $id++ . "\n";
            echo "data: " . $value . "\n\n";
            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" />
    <title>Leash</title>
    <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"></script>
    <script>
var source = new EventSource("/EventSource.php");
source.addEventListener("message", function(message) {
    console.log(JSON.parse(message.data).message);
});
    </script>
    <body>
        <textarea></textarea>
    </body>
</html><?php } ?>

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

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秒后完成。

有人知道如何解决这个问题吗?

编辑

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

我试过了:

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

没有成功。

我正在查看Server-side PHP event page not loading when using while loop,但解决方案不起作用,代码给出了与 OP 相同的错误(他没有太多的代表,所以他可能在 SO 上不活跃),我的至少显示了事件但是我要打破循环,他的代码有无限循环。

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

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 有这个:

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

所以我也尝试过,将.user.init 文件设置为:

output_buffering = 0

output_buffering = Off

但它也没有奏效。脚本正在等待立即返回所有内容。本文中的代码Streaming PHP - disabling output buffering in PHP, Apache, Nginx, and Varnish 如果我使用$string_length = 4096;,即使那个 phpinfo 说该目录的输出缓冲区在本地被禁用。

EDIT2

似乎flush 正在我的共享主机https://jcubic.pl/01.php?size=100 上工作,但我无法在Fedora 上本地测试它,因为flush 不起作用。

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

【问题讨论】:

  • 服务器有一些压缩(gzip或类似的)?
  • @kikko088 zlib.output_compression 设置为关闭
  • 尝试添加header("X-Accel-Buffering: no")
  • @kikko088 没有帮助。

标签: php apache eventsource


【解决方案1】:

我已经通过 apache 启用 gzip 压缩 这个问题的答案解决了这个问题:

Disable Gzip Compression in .htaccess file

【讨论】:

  • 这是很久以前的事了,但似乎这个解决方案在 Fedora 中与我的共享主机一样不起作用。网络标签说 gzip 没有打开,它仍然一次显示所有消息。
猜你喜欢
  • 2015-04-11
  • 1970-01-01
  • 2017-09-02
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多