我想从我的 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 测试脚本是为了证明服务器设置没问题。
如果问题只出在 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();
}