如何从Node.js服务器检测客户端断开连接

5
我是一名新手,正在学习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);

如何知道客户端的互联网断开连接。
1个回答

5
检测“死亡套接字”的最佳方法是发送定期的应用程序级ping / keepalive消息。该消息的外观取决于您用于在套接字上通信的协议。然后,只需使用计时器或其他检查方式,在向客户端发送ping / keepalive消息后,在一定时间内是否收到了“ping响应”即可。
在半相关的笔记中,看起来您正在使用JSON消息进行通信,但您假定每个事件都有完整的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的做法)。
有许多方法可行。但是您还可以考虑在客户端执行相同操作,以便您知道服务器未失去其连接。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接