Node.JS + WebSocket = near real offline/online check

The problem is well know : the online/offline state is not reliable on many browser, this create a difficult situation for developers who wants to create an offline solution : if you don’t know when the client is online or offline, this became difficult to manage (for example) a local backup before having a new connection.

Note : if you already use socket.io, you can combine with existing one, because here I only use basic event from socket.io (in this case, you only need the client part).

With this simple trick on client side and server side, I was able to manage (at +/- 5sec) a good online/offline test :

Server :

Here I use console from previous page here but if you don’t want, just replace « cs. » by « console. »

"use strict";
/* ************************************************************************

	Licence : LGPLv3

	Version: 0.1

	Authors: deisss

	Date: 2012-07-02

	Date of last modification: 2012-07-02

	Description: ping client (tested on socket.io 0.9.6 & Node.JS 0.8.1)

************************************************************************ */

//Redirect all stdout/stderr to file
var cs = require('../common/console.js');

/**
 * Function to broadcast a ping emit, this allow client to know the online/offline state
 * @param socket.io io An socket.io instance
 */
module.exports.ping = function(io){
	io.of("/ping").on("connection", function(socket){
		/* ***************************
		EVENT FROM socket.io
		*****************************/
		socket.on("connect", function(){
			cs.log("ping : user connect");
		});
		socket.on("disconnect", function(){
			cs.log("ping : user disconnect");
		});
	});
};

Just pass a socket.io to this module like this :

var socketio   = require("socket.io").listen(7070, {log:false}),
	ping       = require("./ping.js"),

ping.ping(socketio);

That’s all, we create in fact a basic (most basic one), ping system from socket.io : this system got nothing except connect/disconnect event, which is enough for us in this case.

Client :

On client side, things get little bit more complicated : as of v0.9.6 of socket.io, there is a lots of event available, here is the list :

  • connect
  • connecting
  • connect_failed
  • message
  • close
  • disconnect
  • reconnect
  • reconnecting
  • reconnect_failed
  • error

In this list, except message event, all other will need to be used for this system.
Consider we define a basic window.isOnline property, which always store the current online state from our system :

  //At the beginning you should start by a false state
  window.isOnline = false;

After this, we can start to build our offine/online support

//One sec
var timeout = 1000;
//Starting socket.io
var t = io.connect("http://localhost/ping", {
	'port': 7070,
	'connect timeout': timeout,
	'reconnect': true,
	'reconnection delay': 2000,
	'max reconnection attempts': 10000,
	'force new connection':true
});


t.on("connect", function(){
	window.isOnline = true;
});
t.on("connecting", function(){
	window.isOnline = false;
});
t.on("connect_failed", function(){
	window.isOnline = false;
});
t.on("close", function(){
	window.isOnline = false;
});
t.on("disconnect", function(){
	window.isOnline = false;
});
t.on("reconnect", function(){
	window.isOnline = true;
});
t.on("reconnecting", function(){
	window.isOnline = false;
});
t.on("reconnect_failed", function(){
	window.isOnline = false;
});
t.on("error", function(){
	window.isOnline = false;
});

t is our socket.io instance, and that’s already done : everytime socket.io loose connection, it will put the online state as false, everytime it succeed to connect, or reconnect, it will put it to true again.
Be carefull, the timeout here is set to short value (1sec), this can lead to have some trouble with low bandwidth… A value of 5 or 7sec is still acceptable and offer already good online/offline idea.
You just need to use windows.isOnline now to have a good idea of online/offline browser current state…

Publicités

4 Commentaires

  1. Francis Bacon

    Why not just use `t.connected`?

    It seems to me you’re reimplementing that functionality.

    • deisss

      I prefer to map the full system, sometimes it seems (depending on system), some event sometimes are not raised… So i prefer to map all events, getting better results doing so.

      I have no idea why this behaviour exist, but for example I could get sometimes disconnect not working (working but no event raised), also I could get connect not raised. And it seems it can be variable depending on person, but in general all events are not raised everytime, at least with the version I use : 0.6.X at that time.

  2. It’s not realtime online status,there is about 15 sec from closing the web page to triggering ‘disconected » event on the server

    • deisss

      That’s why I said it’s « near real offline/online » in the title 😉

      But you can control it, and drop it to 0 if you want (I do not recommand that…), simply search for socket.io timeout in google !

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :