Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect client disconnection from node.js server

I am new to node.js. How to detect client is disconnected from node.js server .

Here is my code:

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);

How to know client side internet disconnection.

like image 730
aleena mathew Avatar asked Jan 15 '15 04:01

aleena mathew


Video Answer


1 Answers

The best way to detect "dead sockets" is to send periodic application-level ping/keepalive messages. What that message looks like depends on the protocol you're using for communicating over the socket. Then it's just a matter of using a timer or other means of checking if you've received a "ping response" within a certain period of time after you sent the ping/keepalive message to the client.

On a semi-related note, it looks like you're using JSON messages for communication, but you're assuming a complete JSON string on every data event which is a bad assumption. Try using a delimiter (a newline is pretty common for something like this, and it makes debugging the communication more human-readable) instead.

Here is a simple example of how to achieve this:

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 ...

});

You could also just have one interval instead of two timers that checks a "last data received" timestamp against the current timestamp and if it exceeds some length of time and we have sent a ping message recently, then you assume the socket/connection is dead. You could also instead send more than one ping message and if after n ping messages are sent and no response is received, close the connection at that point (this is basically what OpenSSH does).

There are many ways to go about it. However you may also think about doing the same on the client side, so that you know the server didn't lose its connection either.

like image 151
mscdex Avatar answered Oct 06 '22 12:10

mscdex