2013-04-04 38 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