是否应将EventSource(SSE)无限期地尝试重新连接? [英] Is an EventSource (SSE) supposed to try to reconnect indefinitely?

查看:325
本文介绍了是否应将EventSource(SSE)无限期地尝试重新连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在利用Server-Sent-Events开发一个项目,并且遇到了一些有趣的事情:Chrome和Firefox之间的连接丢失处理方式有所不同.

I'm working on a project utilizing Server-Sent-Events and have just run into something interesting: connection loss is handled differently between Chrome and Firefox.

在Chrome 35或Opera 22上,如果您断开与服务器的连接,它将尝试每隔几秒钟无限期地重新连接,直到成功为止.另一方面,在Firefox 30上,它将仅尝试一次,然后您必须刷新页面或处理引发的错误事件并手动重新连接.

On Chrome 35 or Opera 22, if you lose your connection to the server, it will try to reconnect indefinitely every few seconds until it succeeds. On Firefox 30, on the other hand, it will only try once and then you have to either refresh the page or handle the error event raised and manually reconnect.

我更喜欢Chrome或Opera的操作方式,但请阅读

I much prefer the way Chrome or Opera does it, but reading http://www.w3.org/TR/2012/WD-eventsource-20120426/#processing-model, it seems as though once the EventSource tries to reconnect and fails due to a network error or other, it shouldn't retry the connection. Not sure if I'm understanding the spec correctly, though.

我之所以要求用户使用Firefox,主要是因为您不能在Chrome上打开具有来自同一URL的事件流的多个选项卡,但是这一新发现可能更多地是个问题.虽然,如果Firefox的行为符合规范,那么我还是会以某种方式解决它.

I was set on requiring Firefox to users, mostly based on the fact that you can't have multiple tabs with an event stream from the same URL open on Chrome, but this new finding would probably be more of an issue. Although, if Firefox behaves according to spec then I might as well work around it somehow.

我现在将继续定位Firefox.这是我处理重新连接的方式:

I'm going to keep targeting Firefox for now. This is how I'm handling reconnections:

var es = null;
function initES() {
    if (es == null || es.readyState == 2) { // this is probably not necessary.
        es = new EventSource('/push');
        es.onerror = function(e) {
            if (es.readyState == 2) {
                setTimeout(initES, 5000);
            }
        };
        //all event listeners should go here.
    }
}
initES();

推荐答案

我以与您相同的方式阅读标准,但是即使没有,也要考虑浏览器错误,网络错误,服务器死机但保持套接字打开状态等等.因此,我通常在SSE提供的重新连接之上添加一个保持活动状态.

I read the standard the same way as you but, even if not, there are browser bugs to consider, network errors, servers that die but keep the socket open, etc. Therefore, I usually add a keep-alive on top of the re-connect that SSE provides.

在客户端,我使用几个全局变量和一个辅助函数来完成此操作:

On the client-side I do it with a couple of globals and a helper function:

var keepaliveSecs = 20;
var keepaliveTimer = null;

function gotActivity() {
  if (keepaliveTimer != null) {
    clearTimeout(keepaliveTimer);
  }
  keepaliveTimer = setTimeout(connect,keepaliveSecs * 1000);
}

然后,我在connect()的顶部调用gotActivity(),然后每次收到消息时. (connect()基本上只是对new EventSource()的调用)

Then I call gotActivity() at the top of connect(), and then every time I get a message. (connect() basically just does the call to new EventSource())

在服务器端,它可以每15秒在正常数据流之上吐出一个时间戳(或某些东西),或者可以使用计时器本身在正常数据流之上吐出一个时间戳(或某些东西).安静15秒钟.

On the server-side, it can either spit out a timestamp (or something) every 15 seconds, on top of normal data flow, or use a timer itself and spit out a timestamp (or something) if the normal data flow goes quiet for 15 seconds.

这篇关于是否应将EventSource(SSE)无限期地尝试重新连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆