2013-04-04 91 views
1

我想从我的socket.io客户端(运行在Node.js)到远程websocket持久连接。我无法控制远程套接字,有时它可能完全失效。我想在发生错误或断开连接时尝试重新连接()。在下面的例子中,我试图测试远程主机拒绝连接的情况。在这种情况下,我想在1秒后尝试重新连接。它会再次调用并退出。socket.io客户端持久重试到不可访问的主机

下面的代码:

var events = require('events'), 
    util = require('util'), 
    io = require('socket.io-client'), 
    url = "ws://localhost:12345", // intentionally an unreachable URL 
    socketOptions = { 
     "transports" : [ "websocket" ], 
     "try multiple transports" : false, 
     "reconnect" : false, 
     "connect timeout" : 5000 
    }; 


// The goal is to have this socket attempt to connect forever 
// I would like to do it without the built in reconnects, as these 
// are somewhat unreliable (reconnect* events not always firing) 

function Test(){ 
    var self = this; 
    events.EventEmitter.call(self); 

    var socket; 

    function reconnect(){ 
     setTimeout(go, 1000); 
    } 

    function go(){ 

     console.log("connecting to", url, socketOptions); 

     socket = io.connect(url, socketOptions); 

     socket.on('connect', function(){ 
      console.log("connected! wat."); 
     }); 

     socket.on('error', function(err){ 
      console.log("socket.io-client 'error'", err); 
      reconnect(); 
     }); 

     socket.on('connect_failed', function(){ 
      console.log("socket.io-client 'connect_failed'"); 
      reconnect(); 
     }); 

     socket.on('disconnect', function(){ 
      console.log("socket.io-client 'disconnect'"); 
      reconnect(); 
     }); 
    } 

    go(); 
} 

util.inherits(Test, events.EventEmitter); 


var test = new Test(); 


process.on('exit', function(){ 
    console.log("this should never end"); 
}); 

当在节点0.11.0运行它,我得到以下几点:

$ node socketio_websocket.js 
connecting to ws://localhost:12345 { transports: [ 'websocket' ], 
    'try multiple transports': false, 
    reconnect: false, 
    'connect timeout': 5000 } 
socket.io-client 'error' Error: connect ECONNREFUSED 
    at errnoException (net.js:878:11) 
    at Object.afterConnect [as oncomplete] (net.js:869:19) 
connecting to ws://localhost:12345 { transports: [ 'websocket' ], 
    'try multiple transports': false, 
    reconnect: false, 
    'connect timeout': 5000 } 
this should never end 

回答

4

ECONNREFUSED是你不管理异常。 试试这个:

process.on('uncaughtException', function(err) { 
    if(err.code == 'ECONNREFUSED'){ 
     reconnect(); 
    } 
} 

编辑

修改的选项是这样的:

socketOptions = { 
    "transports" : [ "websocket" ], 
    "try multiple transports" : false, 
    "reconnect" : false, 
    'force new connection': true, // <-- Add this! 
    "connect timeout" : 5000 
}; 

和重新连接功能(看在为解释评论)

function reconnect(){ 
    socket.removeAllListeners(); 
    setTimeout(go, 1000); 
} 

可能是socket.io重新使用相同的连接而不创建新的连接,强制它的应用程序工作

+1

这是不正确的,''socket.on('错误'...'捕捉这个错误,它甚至再次调用reconnect(记录连接代码)。在这一点上它保释。 – Zach 2013-04-04 13:27:04

+0

行动,你说得对。无论如何,你必须做一些修正,在重新连接功能中,你需要删除套接字的监听器,否则每个监听器都会有多个副本。 – 2013-04-04 14:42:51

+0

这是门票! socket.io文档需要一些工作,找到你在[force new connection](https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO)和[removeAllListeners]( http://stackoverflow.com/a/9696077/325652) – Zach 2013-04-04 18:50:30