我有一个长时间运行的任务(for循环每次迭代1秒睡眠),我想在每次迭代更新进度条,我使用HTML5服务器发送的事件,但请求状态等待10秒,在更新完成进度条之后,这意味着它不是实时的,我应该说我在许多PC,笔记本电脑,手机......上用各种操作系统和网络浏览器检查了我的代码。它正在处理所有这些问题,就在我的笔记本电脑上,Windows 7 Home Premium无法正常工作!当它在localhost上工作时,我也在互联网上发现了一个SSE的演示(SSE Demo),它也在我的笔记本上工作。我很困惑!!,任何想法? 谢谢先进。Yii2 HTML5服务器发送的事件不是服务器上的实时
视图文件(sse.php):
<?php
use yii\helpers\Html;
$this->title = Yii::t('app', 'Server-Sent Event');
$this->params['breadcrumbs'][] = $this->title;
$js = '
var es;
function startTask() {
es = new EventSource("'.Yii::$app->urlManager->createUrl('province/default/sse').'");
//a message is received
es.addEventListener("message", function(e) {
var result = JSON.parse(e.data);
addLog(result.message);
if(e.lastEventId == "CLOSE") {
addLog("Received CLOSE closing");
es.close();
var pBar = document.getElementById("progressor");
pBar.value = pBar.max; //max out the progress bar
}
else {
var pBar = document.getElementById("progressor");
pBar.value = result.progress;
var perc = document.getElementById("percentage");
perc.innerHTML = result.progress + "%";
perc.style.width = (Math.floor(pBar.clientWidth * (result.progress/100)) + 15) + "px";
}
});
es.addEventListener("error", function(e) {
addLog("Error occurred");
es.close();
});
}
function stopTask() {
es.close();
addLog("Interrupted");
}
function addLog(message) {
var r = document.getElementById("results");
r.innerHTML += message + "<br>";
r.scrollTop = r.scrollHeight;
}
$(document).on("click", "#start_task", function() {
startTask();
});
$(document).on("click", "#stop_task", function() {
stopTask();
});
';
$this->registerJs($js);
?>
<div class="clearfix"></div>
<div class="box box-solid box-primary">
<div class="box-header">
<h3 class="box-title"><?= Html::encode($this->title) ?></h3>
</div>
<div class="box-body">
<br />
<input type="button" id="start_task" value="Start Long Task" />
<input type="button" id="stop_task" value="Stop Task" />
<br />
<br />
<p>Results</p>
<br />
<div id="results" style="border:1px solid #000; padding:10px; width:300px; height:250px; overflow:auto; background:#eee;"></div>
<br />
<progress id='progressor' value="0" max='100' style=""></progress>
<span id="percentage" style="text-align:right; display:block; margin-top:5px;">0</span>
</div>
</div>
控制文件(DefaultController):
<?php
namespace frontend\modules\province\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\BadRequestHttpException;
/**
* Default controller for the `province` module
*/
class DefaultController extends Controller
{
public function actionTestSse()
{
return $this->render('sse');
}
public function actionSse()
{
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
for($i = 1; $i <= 10; $i++) {
$this->send_message($i, 'on iteration ' . $i . ' of 10' , $i*10);
sleep(1);
}
$this->send_message('CLOSE', 'Process complete', 100);
}
public function send_message($id, $message, $progress) {
$d = array('message' => $message , 'progress' => $progress);
echo "id: $id" . "\n\n";
echo "data: " . json_encode($d) . "\n\n";
echo "\n\n";
ob_flush();
flush();
}
}
您的请求没有完成,直到你的行动结束时,也就是当服务器实际上发回了整个10个周期的响应。您为服务器发送的事件配置的操作是检查状态的操作,而不是执行实际工作的操作。 – marche
marche它在localhost上工作,但不在服务器上,今天我用chrome在android上检查它,它工作正常!不能用Chrome或Firefox在windows上工作! – SADi
我看不出它会如何处理你的代码。每一个使用send_message的函数都会返回给用户,这就是为什么你在请求的整个10秒内得到挂起状态的原因。您回复的所有内容都会作为HTML5 Server-Sent Event所做的单个请求的响应发回给用户。 – marche