不要缓冲事件流的响应

问题描述

我在带有 PHP/7.4.19 的 Nginx/1.14.1 服务器上使用 CodeIgniter 3 PHP 框架。

我正在尝试设置事件流。控制器方法如下所示:

public function foo()
{           
    
    // Try everything I can to disable output buffering
    ini_set('output_buffering','Off');
    ini_set('implicit_flush','On');
    ini_set('zlib.output_compression','Off');
    
    header('X-Accel-Buffering: no');
    header("X-Robots-Tag: noindex");
    header('Cache-Control: no-store,no-cache');
    header('Content-Type: text/event-stream');
    header('content-encoding: none');
    
    $i = 0;
                   
    // Loop 10 times
    while ($i < 10)
    {

        // Codeigniter built-in function to generate a random alphanumeric string of n characters
        $random_string = random_string('alnum',10);
        
        $array = array(
            'foo' => $random_string               
        );
        
        // Put together an event
        $output = "event: ping\n";
        $output .= "id: $random_string\n";
        $output .= "data: ";
        $output .= json_encode($array);
        $output .= "\n\n";         
        
        echo $output;
        
        $i++;
        
        ob_end_flush();
        flush();
        
        // Break the loop if the client closed the page
          
        if (connection_aborted())
        {
            break;
        }
        
        sleep(1);
    }    

预期行为是每个事件一次一个,每秒一个

但是,我似乎无法禁用输出缓冲。在所有 10 个事件完全加载之前,整整 10 秒过去了。

如果我生成一个大的随机字符串,例如 random_string('alnum',500);,那么页面会以大约 4K 的字符块加载。换句话说,页面将大约每约 4K 个字符刷新缓冲区,并且在页面之前需要大约 3 个这些块(每个块之间等待 2-3 秒,以适应 while 循环的 2-3 次迭代)加载完毕。

我正在使用 Cloudflare,但我有一个页面规则可以绕过相关页面上的缓存。这是第一页规则。

在 Cloudflare 中禁用响应缓冲。认情况下,Cloudflare 会在客户端收到数据包时将数据包发送到客户端。企业帐户(我们不是)可以选择启用响应缓冲。

Cloudflare brotli 压缩已启用。暂时禁用它并没有解决问题。

显然,当从命令行运行 PHP 脚本时,它按预期工作。

解决方法

通过在回显输出之前添加行 $output .= str_pad('',4096) . "\n\n";,我能够在 Chrome 中实现所需的结果。

然而,虽然这个解决方案/hack“有效”,但它似乎并没有禁用缓冲,这就是我的问题。

更新:我发现这个 hack 在 Safari 中不起作用。