i want to send "server sent events" SSE from my yii2 application. when i try this script (without yii2), line after line is being print immediately, each after a one-second pause.
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);
}
when i try this action (extending yii\base\Controller
), the output is being buffered and sent as once, after 3 seconds.
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;
}
}
So, how can i configure yii's controller to dump raw output immediately, without buffering, to make sse work? sse.php test script is meant to prove that server settings are ok.
If the problem is only in the Yii, then perhaps this additional will help:
Yii::$app->response->stream = true;
However, both versions of your code worked fine for me locally with Yii2, but did not work on the hosting. This additional helped me:
@ob_end_clean();
ini_set('output_buffering', 0);
Here is the full code of the method if anyone needs it:
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();
}