Comprendre les WebSockets : fonctionnement, cas d'usage et mise en œuvre

Qu'est-ce qu'un WebSocket ?

Schéma du handshake WebSocket entre client et serveur
Le handshake WebSocket transforme une connexion HTTP en canal full-duplex persistant

Un WebSocket est un protocole de communication réseau qui établit un canal bidirectionnel et persistant entre un client et un serveur. Normalisé par le RFC 6455 en 2011, il résout une limitation structurelle du protocole HTTP : son modèle requête-réponse unidirectionnel.

Là où une requête HTTP classique oblige le client à initier chaque échange, le WebSocket autorise le serveur à pousser des données vers le client à tout moment, sans sollicitation préalable. Cette différence fondamentale ouvre des possibilités que le Web ne pouvait pas offrir avec les seuls outils du HTTP standard.

Le problème que résolvent les WebSockets

Comparaison entre le polling HTTP et la communication WebSocket en temps réel
Le polling HTTP gaspille des ressources ; le WebSocket maintient une connexion ouverte et réactive

Avant les WebSockets, les développeurs qui souhaitaient des fonctionnalités temps réel devaient recourir à des artifices. La technique la plus répandue était le polling : le client envoie une requête HTTP au serveur toutes les quelques secondes pour vérifier si de nouvelles données sont disponibles. Cette approche présente deux défauts majeurs.

D'une part, elle génère une charge superflue : chaque requête transporte des en-têtes HTTP complets (plusieurs centaines d'octets) pour une réponse qui, la plupart du temps, ne contient aucune nouvelle donnée. Avec des milliers de clients, la bande passante gaspillée devient significative. D'autre part, elle introduit une latence incompressible : même si le serveur dispose d'une information immédiatement, le client ne la recevra qu'au prochain cycle de polling. Pour une application de chat ou de trading, cette latence est rédhibitoire.

Le long-polling améliore légèrement le modèle en maintenant la connexion ouverte jusqu'à ce que le serveur ait une réponse, mais il conserve les inconvénients structurels du HTTP et complique la gestion des timeouts et des reconnexions.

Comment fonctionne la connexion WebSocket

L'établissement d'une connexion WebSocket se déroule en trois phases.

Première phase : le handshake. Le client envoie une requête HTTP standard au serveur, avec un en-tête spécifique : Upgrade: websocket. Cette requête signale au serveur que le client souhaite basculer le protocole de HTTP à WebSocket. Si le serveur accepte, il répond avec un statut 101 Switching Protocols.

Deuxième phase : la communication bidirectionnelle. Une fois le handshake validé, la connexion HTTP est abandonnée au profit du protocole WebSocket. Les deux parties peuvent désormais envoyer et recevoir des messages de manière totalement indépendante, sans surcharge d'en-têtes. Chaque message est encapsulé dans une trame légère (quelques octets seulement).

Troisième phase : la fermeture. À tout moment, le client ou le serveur peut initier la fermeture de la connexion en envoyant une trame de fermeture. L'autre partie accuse réception, et la connexion est libérée.

Cas d'usage concrets

Illustration des cas d'usage des WebSockets : chat, trading, notifications, jeux
Les WebSockets sont devenus indispensables pour toute application nécessitant des mises à jour en temps réel

Les WebSockets sont aujourd'hui déployés dans des contextes variés où la réactivité est critique.

Applications de messagerie et chat. C'est le cas d'usage historique. Slack, Discord et WhatsApp Web utilisent tous les WebSockets pour acheminer les messages instantanément sans passer par un polling constant.

Tableaux de bord en temps réel. Les plateformes d'analytics (Google Analytics, Datadog, Grafana) affichent des métriques qui se mettent à jour à la seconde. Sans WebSockets, chaque mise à jour nécessiterait un rechargement complet de la page ou un polling coûteux.

Applications collaboratives. Google Docs, Notion et Figma synchronisent les modifications de plusieurs utilisateurs simultanés via des connexions persistantes. Les WebSockets y jouent un rôle central dans la diffusion des changements.

Jeux multijoueurs et trading financier. Ces secteurs exigent la latence la plus faible possible. Les WebSockets permettent de transmettre les positions des joueurs ou les cotations boursières en moins de 100 millisecondes.

Mise en œuvre côté serveur

La plupart des environnements serveur proposent aujourd'hui des bibliothèques WebSocket matures. Voici deux exemples représentatifs.

Avec Node.js et la bibliothèque ws :

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
  ws.on('message', (message) => {
    console.log('Reçu :', message.toString());
    ws.send('Message bien reçu');
  });
  ws.send('Connexion établie');
});

Avec Python et FastAPI :

from fastapi import FastAPI, WebSocket

app = FastAPI()

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    while True:
        data = await websocket.receive_text()
        await websocket.send_text(f"Reçu : {data}")

Ces exemples minimalistes montrent à quel point l'API est simple comparée à la mise en place d'un système de polling équivalent. Le protocole gère automatiquement le handshake, le tramage des messages et la fermeture de connexion.

Mise en œuvre côté client

Dans le navigateur, l'API WebSocket est native et ne nécessite aucune bibliothèque supplémentaire :

const ws = new WebSocket('ws://localhost:8080');

ws.onopen = () => console.log('Connecté');
ws.onmessage = (event) => console.log('Message :', event.data);
ws.onerror = (error) => console.error('Erreur :', error);
ws.onclose = () => console.log('Déconnecté');

// Envoyer un message
ws.send('Hello depuis le navigateur');

Quatre événements structurent le cycle de vie : open (connexion établie), message (données reçues), error (erreur réseau ou protocole) et close (connexion terminée). La méthode send() permet d'émettre un message texte ou binaire vers le serveur.

Limites et bonnes pratiques

Les WebSockets ne sont pas une solution universelle. Ils présentent des contraintes qu'il convient d'anticiper.

Reconnexion. Les connexions WebSocket peuvent être interrompues par des problèmes réseau, des timeouts proxy ou des redémarrages serveur. Une stratégie de reconnexion exponentielle est indispensable : tenter une reconnexion après 1 seconde, puis 2, 4, 8 secondes, jusqu'à un plafond raisonnable.

Sécurité. La version non chiffrée (ws://) doit être réservée au développement local. En production, wss:// (WebSocket over TLS) est obligatoire pour garantir la confidentialité des échanges. L'authentification doit être effectuée au moment du handshake, via un token transmis dans l'URL ou un cookie de session.

Passage à l'échelle. Une connexion WebSocket étant persistante, son coût mémoire sur le serveur est d'environ 10 à 20 Ko par connexion. Pour des applications à grande échelle, un gestionnaire de connexions comme Redis Pub/Sub permet de synchroniser les messages entre plusieurs instances serveur.

FAQ

Les WebSockets sont-ils supportés par tous les navigateurs ?
Oui, l'API WebSocket est supportée par tous les navigateurs modernes depuis 2015, y compris Internet Explorer 11. Le taux d'adoption dépasse 97 % des navigateurs en usage.

Quelle est la différence entre WebSocket et SSE (Server-Sent Events) ?
SSE permet uniquement au serveur d'envoyer des données vers le client (unidirectionnel), mais il bénéficie d'une reconnexion automatique native et fonctionne sur le protocole HTTP standard. Le WebSocket est bidirectionnel mais nécessite un serveur compatible.

WebSocket ou gRPC streaming pour le temps réel ?
gRPC offre des performances supérieures et un typage fort grâce à Protocol Buffers, mais il nécessite un support HTTP/2 et n'est pas disponible dans le navigateur sans couche de traduction. Pour une application web classique, les WebSockets restent le choix le plus pragmatique.

Link_