檢測「死鎖」的最好方法是定期發送應用級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的作用)。
有很多方法可以做到。但是,你也可以考慮在客戶端做同樣的事情,以便你知道服務器也沒有失去它的連接。
你能給個示例代碼 –
添加示例代碼 – mscdex
非常感謝你mscdex,它的工作 –