【问题标题】:How to detect client disconnection from node.js server如何检测客户端与 node.js 服务器的断开连接
【发布时间】:2015-01-15 04:44:01
【问题描述】:

我是 node.js 的新手。如何检测客户端与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);

如何知道客户端断网。

【问题讨论】:

    标签: javascript node.js disconnect


    【解决方案1】:

    检测“死套接字”的最佳方法是定期发送应用程序级别的 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 消息,如果在发送 n ping 消息之后没有收到响应,则在此时关闭连接(这基本上是 OpenSSH 所做的)。

    有很多方法可以解决这个问题。不过,您也可以考虑在客户端做同样的事情,这样您就知道服务器也没有失去连接。

    【讨论】:

      猜你喜欢
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      • 2012-10-11
      • 2021-04-06
      • 1970-01-01
      相关资源
      最近更新 更多