javascript - 服务器发送的事件 : How do you automatically reconnect in a cross-browser way?

标签 javascript php firefox server-sent-events

我实现了一些代码来查询数据库的任何更改并发送事件。 这是我的 PHP 脚本的代码

header("Content-Type: text/event-stream");
header('Cache-Control: no-cache');

//****Some code here to query the database

echo "event: message\n";
echo "data: change_from_database \n";
echo "\n\n";
ob_flush();
flush();

我依靠浏览器在每次连接关闭时自动重新连接,所以我没有在我的服务器代码上实现任何循环。另外,我从this thread中了解到实现无限循环有很多缺点。

所以客户端一切正常:每次连接关闭时浏览器重新连接,每次服务器发送一个事件时都会触发一个事件;好吧,除了不会重新连接的 Firefox (40.0.2)。我知道这不是因为我写了一些 JavaScript 错误检查代码来测试它:

var evtSource = new EventSource("../sse.php");
evtSource.onerror = function(event){
    var txt;
    switch( event.target.readyState ){
    case EventSource.CONNECTING:
        txt = 'Reconnecting...';
        break;
    }
    console.log(txt);
}

因此,每隔一秒,例如 chrome 上的控制台就会记录 “Reconnecting”。另一方面,Firefox 会重新连接一次,然后再也不会这样做。

我如何编写代码才能在 Firefox 以及其他支持服务器发送事件但不自动重新连接的浏览器上运行?

最佳答案

使用最新版本的 Firefox 浏览器 (44.0.2),您的代码可以完美运行。但是,您可以像这样在错误处理程序中重新初始化您的 EventSource 对象:

var evtSource = new EventSource("../sse.php");
var evtSourceErrorHandler = function(event){
    var txt;
    switch( event.target.readyState ){
        case EventSource.CONNECTING:
            txt = 'Reconnecting...';
            break;
        case EventSource.CLOSED:
            txt = 'Reinitializing...';
            evtSource = new EventSource("../sse.php");
            evtSource.onerror = evtSourceErrorHandler;
            break;
    }
    console.log(txt);
}

但我强烈不建议你这样做,因为你的代码没有使用保持连接的好处(正如你所写的,你知道无限循环)所以浏览器会进行简单的轮询(你可以在 then 中看到这个网络选项卡)。我看不出有任何理由在不保持永久连接的情况下通过 AJAX 使用 SSE,这显然很难用 PHP 维护。所以我假设在这种情况下使用简单的 AJAX 轮询。

关于javascript - 服务器发送的事件 : How do you automatically reconnect in a cross-browser way?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32079582/

相关文章:

javascript - Angular 组件路由器从 URL 中删除 #

php - mySQL 连接三个表并搜索在一个表中找到的多个关键字

php - PHP 中有 "nullsafe operator"吗?

html - Firefox 按钮中的图像未对齐

javascript - php 在 Firefox 和 Chrome 中流式传输 wav

asp.net - 如何获取TreeView中TreeNode的ClientID?

javascript - 如何用按钮在不同的div中滑动

javascript - 无法使用 Java 和 Angular js 在一个请求中上传多张图像

php - Symfony 4 自定义反序列化器返回实体中的空属性

ssl - 如何以编程方式将证书添加到 Firefox 版本 59,在 firefox 文件夹中找不到 cert9.db