Le Web n’est plus une simple succession de pages liées entre elles via des liens hypertextes. De plus en plus, ce sont de véritables applications que l’on retrouve, proposant des degrés d’interactivité et de réactivité de plus en plus importants, et nécessitant une communication maximale entre serveur et client.
HTTP est un mode de transport unidirectionnel : le client envoie une requête, le serveur répond puis la connexion est fermée. Ceci pose évidement un problème si on veut continuellement pousser des données vers le client.
Nous allons montrer dans cet article comment Socket.IO propose une façon unifiée d’établir une communication bidirectionnelle entre client et serveur afin de s’affranchir des limitations des navigateurs.
Socket.IO est une bibliothèque JavaScript utilisable côté serveur avec Node.js, ou côté client dans un navigateur.
Elle permet d’abstraire la communication temps réel en utilisant un mécanisme de transport permettant des connexions longues.
Si les Websockets sont disponibles dans le navigateur c’est elles qui seront choisies, sinon plusieurs autres techniques sont essayées (socket Flash, long polling AJAX, …).
L’API fournie est très simple à apprendre et à comprendre, et elle permet une grande souplesse dans le développement d’applications temps réel en JavaScript.
L’installation se fait simplement via npm
, le gestionnaire de paquets de
Node.js :
npm install socket.io
Vous pouvez utiliser l’option -g
de npm pour l’installer au niveau global
(auquel cas vous aurez sûrement besoin des droits d’administration).
Si vous installez en local, npm
va créer un dossier node_module
dans lequel
il va stocker le contenu de la bibliothèque et de ses dépendances.
Afin de voir la structure des messages échangés, on peut utiliser l’application de test suivante :
var app = require('http').createServer(handler),
io = require('socket.io').listen(app)
app.listen(3000);
function handler (req, res) {
res.writeHead(200);
res.end("<html><script src=\"/socket.io/socket.io.js\"></script><script></html>");
}
io.sockets.on('connection', function (socket) {
socket.on('message', function (data) {
socket.broadcast.emit('message', data);
});
});
Celle-ci retransmet à tous les clients les messages qu’elle reçoit.
Pour la tester, enregistrez là dans un fichier broadcast.js
, installez
Socket.IO avec npm
puis lancez là avec node broadcast.js
.
Vous pouvez ensuite ouvrir un navigateur à l’adresse http://localhost:3000/ et ouvrir la console de ce dernier.
Comme vous pouvez le voir, Socket.IO sert automatiquement le fichier
JS du client à l’URL /socket.io/socket.io.js
. Ceci est très pratique car ça
garantit qu’on utilise la bonne version du client par rapport à celle du
serveur.
Pour le reste du code, on crée une application HTTP via la bibliothèque du même nom (livrée en standard avec Node.js), on l’attache au port 3000 et on attache notre application Socket.IO dessus (ligne 2).
Le handler se contente de servir le script.
Les 5 dernières lignes spécifient le comportement de l’application lorsqu’elle reçoit des messages via Socket.IO.
Ici, on attache sur toute socket établie un gestionnaire pour le message de nom
message
. Ce gestionnaire va simplement retransmettre le message à tout les
autres clients.
Pour tester le comportement, utilisez la console du navigateur et tapez les lignes suivantes :
var socket = io.connect('http://localhost:3000')
socket.emit('message', {message: "Bonjour!"})
Vous verrez alors dans votre console que l’application écrit le contenu du message dans toutes les sockets exepcté l’initiatrice du message (vous pouvez mettre ce comportement en évidence en ouvrant plusieurs navigateurs).
Côté client, vous pouvez aussi attacher des gestionnaires. Dans la console du premier navigateur, exécutez :
socket.on('message', function(data) { console.log(data) });
Dans le deuxième navigateur, exécutez de nouveau l’appel à emit
et vous verrez
apparaître une ligne dans la console du premier.
Afin d’explorer un peu plus les possibilités de Socket.IO, je vous recommande en premier lieu la lecture du How-To sur le site officiel, puis des pages du wiki qui détaillent certains points manquants du How-To.
Sans rentrer dans les détails, Socket.IO vous permettra aussi :
Ce dernier point permet notamment de mettre en place extrêmement rapidement un système de messagerie de type pub/sub, non sans rappeler ce que propose Faye, une bibliothèque spécialisée dans ce mode de communication.
Pour que vous puissiez expérimenter un peu plus en profondeur, j’ai mis à disposition le code d’une application permettant en plus du traditionnel chat, d’effectuer des jets de dés, comme pour simuler une table de jeu (de dés donc).
Ce code utilise notamment le principe de salons pour que les joueurs puissent se regrouper facilement sur différentes tables.
Vous retrouverez ce code sur le dépot synbioz/dicetable sur GitHub.