Pra*_*ran 3 php server-sent-events
我正在使用服务器发送的事件来查询数据库中的新记录并向用户显示事件
这是我的代码
javascript
window.onload = function setDataSource() {
if (!!window.EventSource) {
var source = new EventSource("polling.php");
source.addEventListener("message", function(e) {
console.log(e.data);
}, false);
source.addEventListener("open", function(e) {
console.log("OPENED");
}, false);
source.addEventListener("error", function(e) {
console.log(e);
if (e.readyState == EventSource.CLOSED) {
console.log("CLOSED");
}
}, false); } else {}}
Run Code Online (Sandbox Code Playgroud)
PHP
<?php
header("Content-Type: text/event-stream\n\n");
include_once dirname(__FILE__) . '/db.php';
session_start();
while (1) {
$response = getnewmessages();
echo 'data: Message '. json_encode1($response)."\n\n";
ob_flush();
flush();
sleep(5);
}
function getnewmessages ()
{
// query database and get new records.
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,每 5 秒获取一次新记录。但这里的问题是,当我手动刷新页面时,页面加载需要很长时间。
当页面加载时,我可以发现 while 循环仍然执行(至少三次)并暂停页面。经过这么长时间页面开始正常加载。所以我怀疑 while 循环正在暂停执行
你能建议我如何克服这种情况吗?或者如何替换 while 循环?
两个问题: 1. PHP 基于文件的会话在使用会话文件时锁定会话文件 2. PHP 在尝试执行某些输出之前无法检测到客户端已断开连接
因此,最坏的情况是,您的刷新脚本会运行,转储所有更新,然后休眠 5 秒钟。如果客户端在完全相同的时刻刷新,则现在需要 5 时间才能发生另一个循环迭代,并生成一些输出,从而使 PHP 意识到连接已关闭。
快速修复:session_write_close()释放会话文件上的锁定,允许发生并行请求。
长期修复:使用比轮询循环更好的方法来检查消息,例如 websockets。