4.3Temps réel avec WebSockets & Socket.IO
L'essentiel en 30 secondes
- Temps réel = le serveur pousse : HTTP requête-réponse ne suffit pas ; le WebSocket ouvre une connexion persistante et bidirectionnelle.
- Socket.IO = événementiel : on émet (
emit) et on écoute (on) des événements, vers un client, tous (broadcast) ou un groupe (rooms). - Réflexe de Salim : Node excelle au temps réel (milliers de connexions persistantes) — reconnexion auto et rooms incluses.
Mini-cas filé — Salim ajoute le chat vendeurs
Les vendeurs de Salim veulent discuter en direct par boutique : un message posté à Alger doit apparaître aussitôt à l'écran des vendeurs de la même boutique, sans recharger. Le polling HTTP (redemander « du nouveau ? » toutes les secondes) est lent et gaspilleur : Salim monte Socket.IO sur son serveur Express, fait rejoindre chaque vendeur à la room de sa boutique, et diffuse chaque message reçu à la room. Quand la connexion tombe, Socket.IO reconnecte seul. Troisième jalon du fil rouge : le serveur pousse, les écrans vivent.
Suite du cas 4.1-4.2 — Salim rend vivante l'API sécurisée.
1. Pourquoi les WebSockets
Le modèle HTTP est « requête-réponse » : le client demande, le serveur répond, la connexion se ferme. Pour le temps réel — chat, notifications, tableau de bord live, jeu multijoueur, suivi de livraison — c'est le serveur qui doit envoyer des données sans qu'on les lui demande, instantanément. Redemander sans cesse (polling) gaspille et reste lent : le compromis fréquence/latence est impossible à gagner.
Le WebSocket résout cela : une connexion persistante et bidirectionnelle, qui reste ouverte et laisse les deux côtés s'envoyer des messages à tout moment, dans les deux sens. C'est le mécanisme fondamental du temps réel sur le web.
2. Socket.IO : émettre et écouter
En Node, la bibliothèque de référence est Socket.IO : elle fonctionne de façon événementielle — on émet des événements (socket.emit('message', donnees)) et on les écoute (socket.on('message', fonction)), côté serveur comme côté client. Le serveur émet vers un client, vers tous (io.emit, diffusion), ou vers des groupes (les rooms : un salon de chat, une boutique, une partie).
Socket.IO ajoute l'indispensable : reconnexion automatique, solutions de repli si les WebSockets sont indisponibles, rooms et namespaces, authentification des connexions. Le chat de Salim tient en quelques lignes : message reçu → diffusé à la room → tous les écrans à jour, instantanément.
3. Les cas d'usage — et l'atout Node
Messageries, notifications en direct, données live (cours, monitoring, scores), collaboration (curseurs, édition partagée), jeux multijoueurs, suivi en direct : dès qu'une application gagne à réagir instantanément, le temps réel entre en jeu — et cette exigence croît. Bonne nouvelle : Node excelle au temps réel, son modèle non-bloquant gérant efficacement des milliers de connexions persistantes simultanées. Maîtriser Socket.IO est une compétence différenciante pour un développeur Node.
Le polling de la dernière chance (scène à ne pas reproduire)
Moralité : une connexion ouverte qui pousse vaut mieux que mille questions sans réponse.
🔎 Exemple concret — 🔎 Exemple concret — Un chat par boutique
Le circuit de Salim, résumé en quatre lignes :
Vendeur rejoint sa room : socket.join('boutique-alger')
Vendeur envoie : socket.emit('message', texte)
Serveur reçoit : socket.on('message', ...) → relaie à la room
Room reçoit : io.to('boutique-alger').emit('message', texte)
Lecture : émettre d'un côté, écouter de l'autre, diffuser à la room.
Leçon : les rooms organisent qui reçoit quoi.
Vocabulaire de la section
- Temps réel
- Situations où le serveur envoie des données au client sans qu'il les demande, instantanément (chat, notifications, données live, jeux).
Exemple simple : Le message d'un vendeur de Salim apparaît aussitôt chez ses collègues.
Ce que ce n'est pas : le chargement d'une page sur demande HTTP classique.
Réflexe : besoin de push instantané ? penser WebSocket.
- WebSocket
- Protocole établissant une connexion persistante et bidirectionnelle : ouverte en continu, messages à tout moment dans les deux sens.
Exemple simple : La connexion ouverte entre le navigateur du vendeur et le serveur de Salim.
Ce que ce n'est pas : des requêtes HTTP répétées en polling.
Réflexe : une connexion, puis des messages — pas des requêtes.
- Socket.IO
- Bibliothèque temps réel de référence en Node : événementielle (emit/on), reconnexion auto, fallbacks, rooms, namespaces.
Exemple simple : Salim l'ajoute à son serveur Express pour le chat des boutiques.
Ce que ce n'est pas : le module WebSocket brut sans reconnexion ni rooms.
Réflexe : commencer par Socket.IO, pas par le brut.
- emit / on
- emit(événement, données) envoie ; on(événement, fonction) reçoit — des deux côtés, client comme serveur.
Exemple simple : Le client émet message, le serveur l'écoute puis le rediffuse.
Ce que ce n'est pas : un appel d'API REST avec réponse unique.
Réflexe : nommer les événements explicitement et les documenter.
- Room
- Groupe de clients vers qui on diffuse sélectivement (un salon, une boutique, une partie).
Exemple simple : La room boutique-alger de Salim isole les conversations par boutique.
Ce que ce n'est pas : une diffusion à tous les connectés sans distinction.
Réflexe : faire rejoindre la room dès la connexion authentifiée.
En pratique — En pratique — Créer une fonctionnalité temps réel
- Mettez en place Socket.IO côté serveur (sur votre serveur HTTP/Express) et connectez un client.
- Émettez et écoutez des événements : le client socket.emit('message', ...), le serveur socket.on('message', ...).
- Diffusez à tous les connectés (io.emit(...)) : réalisez un chat simple où chaque message reçu est renvoyé à tous.
- Organisez avec des rooms : faites rejoindre un salon et diffusez uniquement dans ce salon, comme Salim par boutique.
Script prêt à dire — justifier Socket.IO (30 s)
« C'est Salim : nos vendeurs ont besoin du direct par boutique, et le polling HTTP gaspille des requêtes pour rester en retard. Je propose Socket.IO : connexion persistante, événements émis et écoutés des deux côtés, diffusion par room de boutique, reconnexion automatique incluse. »
À dire en point technique ; montrez la différence polling vs push.
Modèle copier-coller — serveur Socket.IO avec rooms (code testé)
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const app = express();
const serveur = http.createServer(app);
const io = new Server(serveur);
io.on('connection', (socket) => {
// Chaque vendeur rejoint la room de sa boutique
socket.on('rejoindre', (boutique) => {
socket.join(boutique);
socket.to(boutique).emit('info', 'Un vendeur a rejoint ' + boutique);
});
// Message reçu → rediffusé à la room de l'émetteur
socket.on('message', (donnees) => {
// donnees = { boutique: 'boutique-alger', texte: 'Bonjour !' }
if (!donnees.boutique || !donnees.texte) return;
io.to(donnees.boutique).emit('message', {
texte: donnees.texte,
date: new Date().toISOString()
});
});
});
serveur.listen(3000);
// Client (navigateur) :
// const socket = io();
// socket.emit('rejoindre', 'boutique-alger');
// socket.emit('message', { boutique: 'boutique-alger', texte: 'Bonjour !' });
// socket.on('message', (m) => console.log(m.texte));
Notifications simples
Un seul événement vers tous (io.emit) suffit : pas besoin de rooms pour un tableau d'alertes global.
Chat par groupe
Comme Salim : une room par boutique, rejointe après authentification — chaque groupe vit sa conversation.
Dashboard de données live
Le serveur émet à intervalle régulier vers une room d'abonnés : les écrans se rafraîchissent seuls.
Connexions fragiles (mobile)
Laissez la reconnexion automatique faire son travail et réémettez l'état actuel à chaque reconnexion.
✓ Bonnes pratiques
- Penser événements (emit/on), pas requêtes.
- Diffuser vers le bon périmètre (un, tous, room).
- Vérifier qui rejoint chaque room.
✗ Pièges fréquents
- Poller en boucle au lieu d'ouvrir un WebSocket.
- Diffuser à tous ce qui concerne une room.
- Accepter des connexions anonymes sans contrôle.
Points clés à retenir
- TEMPS RÉEL = le serveur POUSSE instantanément (chat, notifications, live, jeux) — impossible en HTTP requête-réponse.
- WEBSOCKET : connexion PERSISTANTE et BIDIRECTIONNELLE, messages à tout moment dans les deux sens.
- SOCKET.IO : ÉVÉNEMENTIEL (emit/on), reconnexion auto, fallbacks, ROOMS. Un client, tous (broadcast), ou une room.
- Node EXCELLE au temps réel (milliers de connexions persistantes). Compétence différenciante.
Défi 48h — appliquez demain
Réalisez un mini-chat à 2 rooms : rejoindre, envoyer, recevoir — puis débranchez le réseau et observez la reconnexion.
- Je peux expliquer WebSocket, emit/on, rooms.
- Je sais pourquoi le polling ne convient pas.
- J'ai 1 chat temps réel à rooms qui fonctionne.
Questions fréquentes
Pourquoi les WebSockets plutôt que des requêtes HTTP répétées (polling) ?
Parce que HTTP est initié par le client : le serveur ne peut pas pousser spontanément. Le polling (redemander « du nouveau ? ») gaspille (requêtes vides, bande passante, batterie) et reste en retard (jusqu'à l'intervalle). Le long polling améliore un peu mais reste un détournement de HTTP. Le WebSocket établit une connexion persistante bidirectionnelle : le serveur pousse instantanément, sans overhead — la bonne solution, élégante et économe.
Quels types d'applications le temps réel permet-il — est-ce rentable à apprendre ?
Chats et messageries, notifications en direct, dashboards live (cours, monitoring, scores), collaboration (édition partagée, curseurs), jeux multijoueurs, suivi en direct (livraisons), enchères et votes live. L'exigence de réactivité croît partout — et Node, avec son modèle non-bloquant taillé pour des milliers de connexions persistantes, y excelle. Pour un développeur Node, c'est un atout différenciant très demandé.
Que permet un WebSocket par rapport à HTTP classique ?