WebSocket en JavaScript : applications temps réel avancées

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : au-delà du WebSocket de base

La compréhension de base de WebSocket permet de créer un simple chat ou des notifications. Cependant, pour construire des applications temps réel de qualité production — jeux multijoueurs, terminaux financiers, systèmes d'édition collaborative — il est nécessaire de maîtriser des techniques avancées. Dans cet article, nous dépasserons le cadre du "Hello, World" et verrons comment créer des applications WebSocket fiables, évolutives et sécurisées avec Node.js.

Nous aborderons quatre domaines clés : la mise à l'échelle avec Redis, la gestion des états et des salles, la sécurité et l'authentification, ainsi que le clustering pour fonctionner sur plusieurs processeurs. Tous les exemples de code sont écrits en JavaScript avec la bibliothèque ws et Node.js.



1. Mise à l'échelle avec Pub/Sub (Redis)

L'une des principales limitations d'un serveur WebSocket est qu'il ne peut pas "communiquer" avec d'autres instances. Si vous avez deux serveurs derrière un répartiteur de charge, un client connecté au serveur A ne recevra pas un message envoyé via le serveur B. La solution est d'utiliser le modèle Pub/Sub (publieur-abonné) basé sur Redis.

Redis agit comme un courtier central : chaque serveur s'abonne à un canal et y publie des messages. Ainsi, un message envoyé par n'importe quel serveur est instantanément diffusé à tous les autres.

const WebSocket = require('ws');const redis = require('redis');

const wss = new WebSocket.Server({ port: 8080 });const publisher = redis.createClient();const subscriber = redis.createClient();

// Abonnement au canal 'broadcast'subscriber.subscribe('broadcast');subscriber.on('message', (channel, message) => { // Diffusion du message à tous les clients connectés wss.clients.forEach(client => { if (client.readyState === WebSocket.OPEN) { client.send(message); } });});

wss.on('connection', (ws) => { ws.on('message', (data) => { // Publication du message dans Redis publisher.publish('broadcast', data.toString()); });});

Cette approche permet de mettre à l'échelle horizontalement votre application de manière quasi illimitée. Lors de l'ajout d'un nouveau serveur, il crée simplement son propre abonnement à Redis.



2. Gestion des salles et des états

Dans la plupart des applications temps réel, il est nécessaire de regrouper les clients par "salles" (salons de chat, lobbys de jeu) et de gérer leur état. Le wss.clients de base n'offre pas cette fonctionnalité. Implémentons un système de salles simple mais efficace.

Nous allons créer un objet rooms, où la clé est le nom de la salle et la valeur est un Set de clients WebSocket. Ajoutons des méthodes pour rejoindre, quitter et diffuser à l'intérieur d'une salle.

const rooms = new Map();

function joinRoom(ws, roomName) { if (!rooms.has(roomName)) { rooms.set(roomName, new Set()); } rooms.get(roomName).add(ws); // Stockage de la salle sur l'objet ws pour un accès rapide ws.room = roomName;}

function leaveRoom(ws) { if (ws.room && rooms.has(ws.room)) { rooms.get(ws.room).delete(ws); if (rooms.get(ws.room).size === 0) { rooms.delete(ws.room); } delete ws.room; }}

function broadcastToRoom(roomName, message, exclude = null) { if (!rooms.has(roomName)) return; rooms.get(roomName).forEach(client => { if (client !== exclude && client.readyState === WebSocket.OPEN) { client.send(message); } });}

const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', (ws) => { ws.on('message', (data) => { const msg = JSON.parse(data); switch (msg.type) { case 'join': joinRoom(ws, msg.room); break; case 'message': broadcastToRoom(ws.room, msg.text, ws); break; } }); ws.on('close', () => leaveRoom(ws));});

Pour gérer l'état (par exemple, position du joueur, curseur), vous pouvez stocker les données dans un Map

Blogs

Book Recommendations