如何在 yii2 中为 SSE 流式输出

问题描述 投票:0回答:1

我想从我的 yii2 应用程序发送“服务器发送的事件”SSE。 当我尝试这个脚本(没有 yii2)时,一行接一行立即打印,每行暂停一秒后。

sse.php

<?php

date_default_timezone_set("Europe/Vienna");
header("Content-Type: text/event-stream");
header('X-Accel-Buffering: no');


$i = 0;

while ($i++ < 3) {
    $curDate = date(DATE_ISO8601);
    echo 'data: ' . json_encode(['message' => $curDate]), "\n\n";


    while (ob_get_level() > 0) {
        ob_end_flush();
    }
    flush();


    if (connection_aborted()) {
        break;
    }

    sleep(1);
}

当我尝试此操作(扩展

yii\base\Controller
)时,输出被缓冲并在 3 秒后发送一次。

SseController.php

<?php

namespace frontend\controllers;

use Yii;

class SseController extends \yii\base\Controller
{
    public function actionStream()
    {
        $this->layout = false;

        Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
        Yii::$app->response->isSent = true;
        Yii::$app->session->close();

        header('Content-Type: text/event-stream');
        header("Cache-Control: no-cache, must-revalidate");
        header("X-Accel-Buffering: no");


        $i = 0;

        while ($i++ < 3) {
            $curDate = date(DATE_ISO8601);
            echo 'data: ' . json_encode(['message' => $curDate]), "\n\n";

            while (ob_get_level() > 0) {
                ob_end_flush();
            }
            flush();


            if (connection_aborted()) {
                break;
            }

            sleep(1);
        }

        Yii::$app->response->statusCode = 404;
        Yii::$app->response->data = null;
    }
}

那么,我如何配置 yii 的控制器立即转储原始输出,无需缓冲,使 sse 工作? sse.php 测试脚本是为了证明服务器设置没问题。

yii2 server-sent-events
1个回答
0
投票

如果问题只出在 Yii 中,那么这个额外的内容也许会有所帮助:

Yii::$app->response->stream = true;

但是,您的代码的两个版本在本地使用 Yii2 对我来说都很好,但在主机上不起作用。这额外帮助了我:

@ob_end_clean();
ini_set('output_buffering', 0);

如果有人需要,这里是该方法的完整代码:

public function yourAction() {
    @ob_end_clean();
    ini_set('output_buffering', 0);
    
    header('Content-Type: text/event-stream');
    header("Cache-Control: no-cache, must-revalidate");
    header("X-Accel-Buffering: no");
    
    echo "data: 1\n\n";
    flush();
    
    sleep(1);
    
    echo "data: 2\n\n";
    flush();
}
© www.soinside.com 2019 - 2024. All rights reserved.