2015-01-15 279 views
1

我是新來的node.j s。如何檢測客戶端與node.j服務器斷開連接。如何檢測客戶端從node.js服務器斷開連接

這裏是我的代碼

var net = require('net'); 
var http = require('http'); 

var host = '192.168.1.77'; 
var port = 12345;// 
var server = net.createServer(function (stream) 
{ 
stream.setEncoding('utf8'); 

stream.on('data', function (data) { 
    var comm = JSON.parse(data); 
    if (comm.action == "Join_Request" && comm.gameId =="game1") // join request getting from client 
    { 
     var reply0 = new Object(); 
     reply0.message = "WaitRoom"; 
     stream.write(JSON.stringify(reply0) + "\0"); 

    } 
}); 

stream.on('disconnect', function() 
{ 
}); 
stream.on('close', function() 
{ 
console.log("Close"); 
}); 
stream.on('error', function() { 
console.log("Error"); 
}); 

}); 

server.listen(port,host); 

如何知道客戶端網絡斷開。

回答

4

檢測「死鎖」的最好方法是定期發送應用級ping/keepalive消息。該消息的外觀取決於您用於通過套接字進行通信的協議。然後,只需使用計時器或其他方式檢查在將ping/keepalive消息發送給客戶端後的某段時間內是否收到「ping響應」。

在半相關說明中,它看起來像是使用JSON消息進行通信,但是您假設每個data事件都有一個完整的JSON字符串,這是一個糟糕的假設。嘗試使用分隔符(換行符在這類事情中很常見,它使調試通信更加人性化)。

下面是如何實現一個簡單的例子:

var PING_TIMEOUT = 5000, // how long to wait for client to respond 
    WAIT_TIMEOUT = 5000; // duration of "silence" from client until a ping is sent 

var server = net.createServer(function(stream) { 
    stream.setEncoding('utf8'); 

    var buffer = '', 
     pingTimeout, 
     waitTimeout; 

    function send(obj) { 
    stream.write(JSON.stringify(obj) + '\n'); 
    } 

    stream.on('data', function(data) { 
    // stop our timers if we've gotten any kind of data 
    // from the client, whether it's a ping response or 
    // not, we know their connection is still good. 
    clearTimeout(waitTimeout); 
    clearTimeout(pingTimeout); 

    buffer += data; 
    var idx; 

    // because `data` can be a chunk of any size, we could 
    // have multiple messages in our buffer, so we check 
    // for that here ... 
    while (~(idx = buffer.indexOf('\n'))) { 
     try { 
     var comm = JSON.parse(buffer.substring(0, idx)); 

     // join request getting from client 
     if (comm.action === "Join_Request" && comm.gameId === "game1") { 
      send({ message: 'WaitRoom' }); 
     } 
     } catch (ex) { 
     // some error occurred, probably from trying to parse invalid JSON 
     } 

     // update our buffer 
     buffer = buffer.substring(idx + 1); 
    } 

    // we wait for more data, if we don't see anything in 
    // WAIT_TIMEOUT milliseconds, we send a ping message 
    waitTimeout = setTimeout(function() { 
     send({ message: 'Ping' }); 
     // we sent a ping, now we wait for a ping response 
     pingTimeout = setTimeout(function() { 
     // if we've gotten here, we are assuming the 
     // connection is dead because the client did not 
     // at least respond to our ping message 
     stream.destroy(); // or stream.end(); 
     }, PING_TIMEOUT); 
    }, WAIT_TIMEOUT); 
    }); 

    // other event handlers and logic ... 

}); 

你也可以只具有一個區間,而不是兩個定時器,檢查了「最後的數據接收」時間戳對當前時間戳,如果超過一段時間,我們最近發送了一條ping消息,然後你認爲套接字/連接已經死了。您也可以發送多個ping消息,如果發送了ping消息並且沒有收到響應,請關閉此時的連接(這基本上是OpenSSH的作用)。

有很多方法可以做到。但是,你也可以考慮在客戶端做同樣的事情,以便你知道服務器也沒有失去它的連接。

+0

你能給個示例代碼 –

+0

添加示例代碼 – mscdex

+0

非常感謝你mscdex,它的工作 –

相關問題