SockJS客户端自动重连?

10

我正在尝试找到一种方法,让我的SockJS客户端在服务器宕机后能够重新连接。

目前我有这个:

    new_conn = function() {    
        socket = new SockJS(protocol + serverDomain + '/echo', null, {
            'protocols_whitelist': ['websocket', 'xdr-streaming', 'xhr-streaming', 'iframe-eventsource', 'iframe-htmlfile', 'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling']
        });
    };

    socket.onopen = function () {
        clearInterval(recInterval);
    };  

    socket.onclose = function () {    
        recInterval = window.setInterval(function () {
            new_conn();
        }, 2000);
    }; 

问题在于setInterval会持续触发,即使成功重连。似乎socket.onopen从未被执行。

有任何想法我可能做错了什么?


3
针对您的情况,使用setTimeout()比setInterval()更好。 - lance34
@Fielding34 实际上我认为相反 - setInterval() 更好,因为 OP 希望在服务器下线时不断尝试连接,直到连接成功。 - TMG
@TMG 如果服务器宕机时尝试连接,则实际上会触发“close”事件,因此只需要一个setTimeout()即可。 - Herohtar
2个回答

10

我认为这可能与变量作用域有关。试试这个:

var recInterval = null;

new_conn = function() {    
    socket = new SockJS(protocol + serverDomain + '/echo', null, {
        'protocols_whitelist': ['websocket', 'xdr-streaming', 'xhr-streaming', 'iframe-eventsource', 'iframe-htmlfile', 'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling']
    });
};

socket.onopen = function () {
    clearInterval(recInterval);
};  

socket.onclose = function () {    
    recInterval = window.setInterval(function () {
        new_conn();
    }, 2000);
}; 

无论如何,这很奇怪,因为你在window对象上声明了recInterval,它应该能够工作。如果它不起作用,你也可以使用浏览器进行调试,使用debugger;语句或通过设置本地断点进行交互式调试...(例如,在onopen中)。

顺便说一下,我像这样重写了整个代码(我喜欢重构:):

var recInterval = null;
var socket = null;

var new_conn = function() {    
    socket = new SockJS(protocol + serverDomain + '/echo', null, {
        'protocols_whitelist': ['websocket', 'xdr-streaming', 'xhr-streaming', 
                                'iframe-eventsource', 'iframe-htmlfile', 
                                'xdr-polling', 'xhr-polling', 'iframe-xhr-polling',
                                'jsonp-polling']
    });

    socket.onopen = function () {
        clearInterval(recInterval);
    };  

    socket.onclose = function () {    
        recInterval = setInterval(function () {
            new_conn();
        }, 2000);
    };
};

8

如果仍有人关注此主题:franzlorenzon的重构代码片段会导致许多重新连接,因为它在某种程度上是递归重新连接自身,每两秒钟就会产生一个新的onclose事件(不考虑recInterval)。

将清除间隔放在套接字创建之后即可解决问题。我还在onclose事件中添加了socket = null。

var recInterval = null;
var socket = null;

var new_conn = function() {
  socket = new SockJS(protocol + serverDomain + '/echo', null, {
    'protocols_whitelist': ['websocket', 'xdr-streaming', 'xhr-streaming',
      'iframe-eventsource', 'iframe-htmlfile',
      'xdr-polling', 'xhr-polling', 'iframe-xhr-polling',
      'jsonp-polling'
    ]
  });

  clearInterval(recInterval);

  socket.onopen = function() {

  };

  socket.onclose = function() {
    socket = null;
    recInterval = setInterval(function() {
      new_conn();
    }, 2000);
  };
};


1
谢谢分享这个。如果有一个后退协议,重新连接尝试之间的时间增加,那就更好了。然后,通过监控应用程序中的滚动来检测用户是否“沮丧”,并降低重新连接时间。显然,他们只需重新加载页面就会触发重新连接尝试。 - coding
@编程 是的,你是正确的。上面的代码只是一个例子,用来修复之前示例中的错误。我们正在我们的生产系统中使用像你建议的解决方案,它运行得很好。我也在私人项目中使用类似的解决方案。同样没有任何问题。 :) - daPhantom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接