Débuter avec Socket.io

Sébastien Chopin

Maintenant que savez comment installer Node JS sur votre ordinateur ainsi que NPM (si ce n'est pas le cas, voir le tutoriel dessus) nous allons nous attaquer à Socket.IO afin de créer notre première application Web en temps réel !

Cet article a été publié avec l'aimable autorisation de Sébastien Chopin. L'article original (Tutoriel Socket.IO (débutant)) peut être vu sur le site d'Atinux.

Commentez ♪

- Titre : Débuter avec Socket.io

- Auteur : Sébastien Chopin

- Parution : 10 juin 2013

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2013 Sébastien Chopin. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- Introduction

- Qu'est-ce que j'entends par temps réel ?

- Qu'allons-nous faire dans ce tutoriel ?

- I. Installation de Socket.IO

- II. Fonctionnement de Socket.IO

- III. Utilisation de Socket.IO

- III-A. Côté serveur

- III-B. Côté client

- III-C. Événements

- III-D. Exemple

- IV. Création de notre application de chat en temps réel !

- IV-A. Fichier app.js

- IV-B. Fichier tchat.html

- V. Conclusion et remerciements

- V-A. Conclusion

- V-B. Remerciements

Introduction

Qu'est-ce que j'entends par temps réel ?

Je trouve que le meilleur exemple est celui du chat, en effet, à chaque fois que vous envoyez un message, votre interlocuteur le reçoit immédiatement sur son écran, ce qui est normal vous allez me dire.

Socket.IO vous permet de faire la liaison entre vous et les autres personnes connectées sur l'application Web, le tout en temps réel !

Je vous laisse donc imaginer tout ce qu'il est possible de faire avec !

Je suis conscient que c'est largement possible d'utiliser des Web sockets avec PHP, Flash, JAVA… mais je trouve cela plus difficile qu'avec Socket.IO, et puis on est ici pour parler de JavaScript.

Qu'allons-nous faire dans ce tutoriel ?

Nous allons créer un chat avec des Web sockets grâce à Node JS ! Mais avant, nous allons voir comment installer Socket.IO et comment il fonctionne.

Vous allez donc être capable à la fin de ce tutoriel de créer par vous-même vos applications Web en utilisant des Web sockets.

I - Installation de Socket.IO

L'installation de Socket.IO va ajouter un dossier node_modules/ dans le dossier de notre projet. Dans ce dossier node_modules/ se trouvera un dossier socket.io/ qui contiendra tous les fichiers propres à la librairie de Socket.IO.

Placez-vous à la racine de votre projet et faites :

npm install socket.io

Voilà vous avez installé Socket.IO pour votre projet, pas trop difficile ? Bon on passe à la suite alors !

II - Fonctionnement de Socket.IO

Socket.IO va nous permettre de faire la liaison en temps réel avec le serveur afin d'appeler ses propres fonctions, de même pour le serveur qui peut appeler des fonctions propres au côté client.
Cette liaison se fait par le biais d'événements que l'on crée et que l'on appelle.

Par exemple, on peut créer un événement sur le serveur qui va utiliser la fonction afficherListeProduit() et qui va appeler un événement du côté client en lui donnant la liste des produits. Cet événement du côté client va par la suite récupérer la liste des produits et l'afficher ! Tout cela sans rafraîchissement de la page et sans appel d'URL (AJAX) ! Magique non ?

Pour information, Socket.IO est compatible avec un très grand nombre de navigateurs dont voici la liste : http://socket.io/#browser-support.

III - Utilisation de Socket.IO

III-A - Côté serveur

Il suffit d'inclure la librairie comme ceci dans votre fichier app.js :

var io = require('socket.io');

Il faut ensuite, après avoir créé le serveur HTTP avec Node JS, faire écouter Socket.IO à celui-ci :

// app est votre serveur (var app = http.createServer...)
io = io.listen(app);

III-B - Côté client

Il faut insérer le lien de la librairie dans le header du .html :

<script type="text/javascript" src="/socket.io/socket.io.js"></script>

Ensuite, il faut dans un nouveau <script> se connecter au serveur :

<script type="text/javascript">
var socket = io.connect();
</script>

III-C - Événements

Socket.IO utilise un système d'événements, en effet, nous allons créer des événements que nous appellerons par la suite à partir du client vers le serveur et vice versa.

Pour créer un événement, il suffit de faire :

socket.on('monEvenement', maFonction);

Comme vous pouvez le voir, la variable socket n'est pas encore déclarée du côté serveur, en effet, il faut la récupérer grâce à l'événement connection :

io.sockets.on('connection', function (socket) {
// Mes événements lorsque le client est connecté !
});

Maintenant que vous savez créer un événement, l'autre chose essentielle est d'en appeler un !

Pour se faire, rien de bien compliqué :

socket.emit('monEvenement', mesDonnees); // le deuxième argument est facultatif

Cela va appeler un événement sur le client actuel qui vient de se connecter.

Si on veut appeler un événement pour tous les clients connectés au serveur sauf celui qui a appelé l'événement, il suffit d'utiliser la méthode broadcast :

socket.broadcast.emit('monEvenement', mesDonnees);

III-D - Exemple

Côté serveur :

app.js

var html = require('fs').readFileSync(__dirname+'/app.html');
var app = require('http').createServer(function(req, res){ res.end(html); });
app.listen(8080);
var io = require("socket.io");
var io = io.listen(app);
io.sockets.on('connection', function (socket) {
socket.emit('faitUneAlerte');
});

Côté client :

app.html

<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect();
socket.on('faitUneAlerte', function () {
alert('Je fais une alerte car on m\'a appelé !');
});
</script>

Résultat.

Je vous laisse installer Socket.IO dans le projet si ce n'est pas déjà fait et ensuite lancer la commande : node app.js.

Lorsque vous vous rendez sur http://localhost:8080 vous devriez voir apparaître une alerte après avoir chargé la page.

Maintenant, on va rajouter un autre événement qui prend en paramètre une chaîne de caractères.

app.js

socket.emit('faitUneAlerte2', 'Je suis fou');

app.html

socket.on('faitUneAlerte2', function (phrase) {
alert(phrase);
});

Comme vous pouvez le voir, vous pouvez transférer des variables à travers les événements !

Vous pouvez aussi transférer des hashs, vous allez le voir dans la création du chat !

IV - Création de notre application de chat en temps réel !

Cette application vous sert à confirmer les connaissances que vous avez pu apprendre dans les chapitres précédents, normalement vous êtes largement capable de réaliser cette application sans aide.

Je pense que les codes source commentés sont parfois plus explicites et plus faciles à comprendre que des centaines de lignes d'explications.
De plus, il ne faut que deux fichiers pour créer notre chat !

IV-A - Fichier app.js

app.js

var http    =   require('http');
var fs      =   require('fs');

// Création du serveur
var app = http.createServer(function (req, res) {
// On lit notre fichier tchat.html
fs.readFile('./tchat.html', 'utf-8', function(error, content) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end(content);
});
});

// Variables globales
// Ces variables resteront durant toute la vie du seveur et sont communes pour chaque client (node server.js)
// Liste des messages de la forme { pseudo : 'Mon pseudo', message : 'Mon message' }
var messages = [];

//// SOCKET.IO ////

var io      =   require('socket.io');

// Socket.IO écoute maintenant notre application !
io = io.listen(app);

// Quand une personne se connecte au serveur
io.sockets.on('connection', function (socket) {
// On donne la liste des messages (événement créé du côté client)
socket.emit('recupererMessages', messages);
// Quand on reçoit un nouveau message
socket.on('nouveauMessage', function (mess) {
// On l'ajoute au tableau (variable globale commune à tous les clients connectés au serveur)
messages.push(mess);
// On envoie à tous les clients connectés (sauf celui qui a appelé l'événement) le nouveau message
socket.broadcast.emit('recupererNouveauMessage', mess);
});
});

///////////////////

// Notre application écoute sur le port 8080
app.listen(8080);
console.log('Live Chat App running at http://localhost:8080/');

IV-B - Fichier tchat.html

tchat.html

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8" />
<title>Tchat avec Socket.IO</title>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<style type="text/css">
body {
background-color : rgb(50,50,80);
color : white;
text-align : center;
}
#tchat {
background-color : white;
opacity : 0.8;
width : 500px;
height : 300px;
margin : auto;
border : 3px rgb(40,40,40) solid;
overflow : auto;
}
.line {
border-bottom : 1px rgb(80,80,80) solid;
padding : 4px;
text-align:left;
color : rgb(40,40,40);
}
</style>
</head>
<body>
<h1>Tchat avec Socket.IO</h1>
<div id="tchat"></div>
<form onsubmit="return (envoiMessage());">
<b>Message : </b><input type="text" name="message" id="message" style="width:250px;" /> <input type="submit" value="Envoyer" />
</form>
<script type="text/javascript">
// On demande le pseudo de l'utilisateur
var pseudo = prompt('Votre pseudo ?') || 'Utilisateur';
// On se connecte au serveur
var socket = io.connect();
// On crée l'événement recupererMessages pour récupérer direcement les messages sur serveur
socket.on('recupererMessages', function (messages) {
// messages est le tableau contenant tous les messages qui ont été écris sur le serveur
var html = '';
for (var i = 0; i < messages.length; i++)
html += '<div class="line"><b>'+messages[i].pseudo+'</b> : '+messages[i].message+'</div>';
document.getElementById('tchat').innerHTML = html;
});
// Si quelqu'un a posté un message, le serveur nous envoie son message avec l'événement recupererNouveauMessage
socket.on('recupererNouveauMessage', function (message) {
document.getElementById('tchat').innerHTML += '<div class="line"><b>'+message.pseudo+'</b> : '+message.message+'</div>';
});
// Quand on veut envoyer un message (on a validé le formulaire)
function envoiMessage(mess) {
// On récupère le message
var message = document.getElementById('message').value;
// On appelle l'événement se trouvant sur le serveur pour qu'il enregistre le message et qu'il l'envoie à tous les autres clients connectés (sauf nous)
socket.emit('nouveauMessage', { 'pseudo' : pseudo, 'message' : message });
// On affiche directement notre message dans notre page
document.getElementById('tchat').innerHTML += '<div class="line"><b>'+pseudo+'</b> : '+message+'</div>';
// On vide le formulaire
document.getElementById('message').value = '';
// On retourne false pour ne pas que le formulaire n'actualise la page
return false;
}
</script>
</body>
</html>

V - Conclusion et remerciements

V-A - Conclusion

Voilà, l'application est déjà terminée, rapide non ?

Vous pouvez aussi retrouver mes autres projets faits avec Socket.IO sur GitHub, le code source est disponible donc faites-vous plaisir pour mieux cerner Socket.IO.

- LiveChat (c'est cette application de chat) : https://github.com/Atinux/LiveChat.

- LiveDraw : application de dessin en temps réel, aussi simple à faire que le chat, mais avec plus de JavaScript pur : https://github.com/Atinux/LiveDraw.

- LiveBalls : chat plus contrôle d'une balle dans l'écran avec la souris plus contrôle des effets visuels pour le mouvement des balles : https://github.com/Atinux/LiveBalls.

Bravo si vous avez réussi à lire jusqu'ici, j'espère avoir été le plus clair possible. N'hésitez pas à me poser des questions dans les commentaires si c'est encore flou sur certains points.

Si vous avez bien compris le fonctionnement des Websockets avec Socket.IO et que vous en voulez plus, je vous invite fortement à lire ce tutoriel en français fait par Naholyr : http://naholyr.fr/2011/07/authentification-et-websocket-avec-node-js-express-et-socket-io/.

V-B - Remerciements

Cet article a été publié avec l'aimable autorisation de Sébastien Chopin. L'article original (Tutoriel Socket.IO (débutant)) peut être vu sur le site d'Atinux.

Nous tenons à remercier Didier Mouronval pour sa relecture attentive de cet article.