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

ale*_*hew 3 javascript disconnect node.js

我是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);
Run Code Online (Sandbox Code Playgroud)

如何知道客户端互联网断开连接.

msc*_*dex 5

检测"死套接字"的最佳方法是定期发送应用级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 ...

});
Run Code Online (Sandbox Code Playgroud)

您也可以只有一个间隔而不是两个定时器来检查当前时间戳的"收到的最后一个数据"时间戳,如果它超过一段时间并且我们最近发送了一条ping消息,那么您认为套接字/连接已经死亡.您也可以发送多个ping消息,如果发送ping消息后n没有收到响应,则关闭此时的连接(这基本上就是OpenSSH的作用).

有很多方法可以解决这个问题.但是,您也可以考虑在客户端执行相同操作,以便您知道服务器也没有丢失其连接.