Pavan K
Pavan K

Reputation: 4693

nodejs websocket detect disconnected socket

I have a nodejs websocket server and I have the following problem.

When my clients connect to the server and terminate gracefully the onclose method is called on those sockets and I perform clean up operations on the closed socket.

When the client disconnects due to network, the onclose method is not called. Is there any timeout to be set so onclose is called automatically after a timeout?

I am using ws package for the websocket server in nodejs

Upvotes: 15

Views: 41550

Answers (4)

Alex Misiulia
Alex Misiulia

Reputation: 1800

You can check it in the official library documentation. I don't want to copy-paste it here because it can be out of date soon.

Upvotes: 2

Pavan K
Pavan K

Reputation: 4693

default ws implementation doesn't have a callback for network disconnects from client side

You can find a keepAlive implementation here

Upvotes: 19

Ehsan
Ehsan

Reputation: 1285

Well I'll try to answer your question with two examples. Try to analyze both of them and learn how they work. They are both tested and working.

1- Websocket:

Server:

var WebSocketServer = require('websocket').server;
var http = require('http');

var server = http.createServer(function(request, response) {
    console.log((new Date()) + ' Received request for ' + request.url);
    response.writeHead(404);
    response.end();
});
server.listen(3000, function() {
    console.log((new Date()) + ' Server is listening on port 3000');
});

wsServer = new WebSocketServer({
    httpServer: server,
    autoAcceptConnections: false
});

function originIsAllowed(origin) {
  return true;
}

wsServer.on('request', function(request) {
    if (!originIsAllowed(request.origin)) {
      request.reject();
      console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
      return;
    }

    var connection = request.accept('echo-protocol', request.origin);
    console.log((new Date()) + ' Connection accepted.');
    connection.on('message', function(message) {
        if (message.type === 'utf8') {
            console.log('Received Message: ' + message.utf8Data);
            connection.sendUTF(message.utf8Data);
        }
        else if (message.type === 'binary') {
            console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
            connection.sendBytes(message.binaryData);
        }
    });
    connection.on('close', function(reasonCode, description) {
        console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
    });
});

Client:

<!DOCTYPE html>
<html>
<head>
    <title>Web socket Experiment</title>
    <script type="text/javascript">
        function callWebSocket() {

            var socket = new WebSocket("ws://localhost:3000", 'echo-protocol');

            socket.onopen = function () {
                alert("Hello, Connected To WS server");
            };

            socket.onmessage = function (e) {
                alert("The message received is : " + e.data);
            };
            socket.onerror = function (e) {
                alert("An error occured while connecting... " + e.data);
            };
            socket.onclose = function () {
                alert("hello.. The coonection has been clsoed");
            };

        }
    </script>
</head>

<body>
    <input type="button" value="Open Connecton" onclick="callWebSocket()" />
</body>
</html>

2- Socket.io:

Server:

var http = require('http');
    var app = require('express')();
    var httpServer = http.createServer(app)
    var io = require('socket.io')(httpServer);

app.get('/', function(req, res) {
    res.sendfile(__dirname + '/index.html');
});

io.on('connection', function(socket) {
    socket.emit('news', {
        hello: 'world'
    });
    socket.on('my other event', function(data) {
        console.log(data);
    });
    socket.on('disconnect', function(data) {
        console.log('disconnect!');
    });
});

httpServer.listen(3000);

Client:

<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
  var conn_options = {
    'sync disconnect on unload':false
  };
  var socket = io.connect('http://localhost:3000',conn_options);
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>
</head>
<body>
</body>
</html>

Upvotes: 4

gzost
gzost

Reputation: 2445

To detect a disconnect, you need to have some traffic. If your application produces constant traffic, then you could do something like reset a counter each time something is received, and consider the connection failed when the counter runs out.

Otherwise you should be able to use the pings that WebSocket offers. These are not exposed in the browser, but your WebSocket library for Node.js may allow you to turn them on and get a notification if a ping fails.

Upvotes: 2

Related Questions