Android上的Chrome:连接在30分钟后就会死机

时间:2017-04-26 08:14:19

标签: javascript chat real-time long-polling server-sent-events

我们正在使用我们自己的通知系统构建一个聊天室,而不依赖于GCM,而是依赖于服务工作者+ SSE。 在桌面上它很好,但在移动Android应用程序(使用cordova-crosswalk,铬53)。 长时间运行的通知连接在20-30分钟后卡住,并且处于前台活动状态。 它不会因为错误而死亡,只是没有回收数据。没有任何错误,这是非常奇怪的。无法重新连接,因为我们根本不知道连接是否已经死亡。

最干净的方法是什么?每5分钟重新启动一次连接是一个想法,但它不干净。 代码

  runEvtSource(url, fn) {
if (this.get('session.content.isAuthenticated') === true) {
  var evtSource = new EventSource(url, {
    withCredentials: true
  });
}}

积极的重新连接代码

var evtSource = this.runEvtSource(url, fn)
var evtSourceErrorHandler = (event) => {
  var txt;
  switch (event.target.readyState) {
    case EventSource.CONNECTING:
      txt = 'Reconnecting...';
      evtSource.onerror = evtSourceErrorHandler;
      break;
    case EventSource.CLOSED:
      txt = 'Reinitializing...';
      evtSource = this.runEvtSource(url, fn)
      evtSource.onerror = evtSourceErrorHandler;
      break;
  }
  console.log(txt);
evtSource.onerror = evtSourceErrorHandler

1 个答案:

答案 0 :(得分:1)

我通常在SSE连接之上添加一个保活层。它不会经常发生,但套接字可以在不正常死亡的情况下死亡,因此您的连接会变得安静而且不会出现错误。

所以,一种方法是,在你的获取数据函数中:

if(timer)clearTimeout(timer);
timer = setTimeout(reconnect, 30 * 1000);
...process the data

换句话说,如果您上次获取数据超过30秒,请重新连接。根据您发送的数据的频率选择一个值:如果10%的时间内数据事件之间有60秒的差距,但是从未有120秒的差距,那么将超时设置为高于120秒的时间是有道理的

您可能还希望通过将常规消息从服务器推送到客户端来保持活力。如果来自服务器的消息频率非常不规则,这是一个好主意。例如。我可能让服务器每30秒发送一次当前时间戳,并在客户端上使用45秒的保持活动时间。

顺便说一句,如果这是一个移动应用程序,请记住,如果用户会欣赏减少接收聊天消息的延迟的好处,而不是缩短电池寿命。