服务器发送的事件:如何以跨浏览器的方式自动重新连接?

che*_*zeh 13 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();
Run Code Online (Sandbox Code Playgroud)

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

所以一切都在客户端工作正常:每次连接关闭时浏览器都会重新连接,每次服务器发送一个事件时都会触发事件; 除了没有重新连接的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);
}
Run Code Online (Sandbox Code Playgroud)

因此,像每一秒后,铬控制台上的控制台例如日志"Reconnecting".另一方面,Firefox重新连接一次,再也不会重新连接.

如何编写代码以使其在Firefox上运行,也许还有其他支持服务器发送事件但不自动重新连接的浏览器?

max*_*max 6

使用最新版本的 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);
}
Run Code Online (Sandbox Code Playgroud)

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