Le protocole HTTP traditionnel fonctionne sur un modèle de requête-réponse : le client sollicite une ressource, le serveur répond, et la connexion se ferme. Bien que ce mécanisme soit parfait pour charger des pages statiques, il s'avère inefficace pour les applications modernes exigeant de la réactivité, comme les chats en ligne, le trading ou les jeux multijoueurs. C'est ici qu'interviennent les WebSockets, en offrant une connexion persistante et bidirectionnelle.

Le fonctionnement technique des WebSockets

Une connexion WebSocket débute par une "poignée de main" (handshake) via HTTP. Le client envoie une requête spécifique contenant l'en-tête Upgrade: websocket. Si le serveur accepte, il renvoie un code 101 Switching Protocols. Dès lors, le tunnel est ouvert : le client et le serveur peuvent s'échanger des données à tout moment sans la lourdeur des en-têtes HTTP répétés.

Handshake WebSocket (Poignée de main)
Client → Serveur :
GET /chat HTTP/1.1
Host: exemple.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

Serveur → Client :
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

HTTP vs WebSockets : Quelle différence ?

  • HTTP : Initié par le client, unidirectionnel par message, sans état (stateless), surcharge importante (headers envoyés à chaque fois).
  • WebSocket : Bidirectionnel (Full-duplex), connexion persistante, avec état, surcharge minimale (tramage de 2 à 14 octets).
  • SSE (Server-Sent Events) : Flux unidirectionnel du serveur vers le client uniquement, basé sur HTTP, souvent plus simple pour les notifications push.

Implémentation côté Navigateur

JavaScript Côté Client
const ws = new WebSocket("wss://api.exemple.com/ws");

// Connexion établie
ws.addEventListener("open", () => {
  console.log("Connecté au serveur !");
  ws.send(JSON.stringify({ type: "join", room: "general" }));
});

// Écoute des messages entrants
ws.addEventListener("message", (event) => {
  const data = JSON.parse(event.data);
  console.log("Message reçu :", data);
});

// Gestion de la fermeture
ws.addEventListener("close", (event) => {
  console.log(`Déconnecté : ${event.code} ${event.reason}`);
});

// Gestion des erreurs
ws.addEventListener("error", (error) => {
  console.error("Erreur WebSocket :", error);
});

Serveur Node.js avec la bibliothèque ws

Côté Serveur (Node.js)
import { WebSocketServer } from "ws";

const wss = new WebSocketServer({ port: 8080 });

wss.on("connection", (ws) => {
  console.log("Nouveau client connecté");

  ws.on("message", (message) => {
    const data = JSON.parse(message);

    // Diffusion à tous les clients connectés (Broadcast)
    wss.clients.forEach((client) => {
      if (client.readyState === 1) {
        client.send(JSON.stringify({
          type: "message",
          text: data.text,
          timestamp: Date.now()
        }));
      }
    });
  });

  ws.on("close", () => {
    console.log("Client déconnecté");
  });
});

Quand privilégier les WebSockets ?

  • ✅ Cas d'usage idéaux : Applications de messagerie, notifications en direct, édition collaborative (type Google Docs), jeux en ligne, tableaux de bord financiers, flux IoT.
  • ❌ À éviter pour : Les API CRUD standards, le téléchargement de fichiers volumineux, la consultation de données peu fréquentes (préférez le polling ou SSE).

Bonnes pratiques pour la mise en production

  • Logique de reconnexion : Les connexions coupent souvent. Implémentez un système de reconnexion avec un délai exponentiel (exponential backoff).
  • Heartbeats (Ping/Pong) : Envoyez des signaux réguliers pour détecter les connexions fantômes et libérer la mémoire du serveur.
  • Sécurité : Utilisez `wss://` (sécurisé). Gérez l'authentification via un jeton JWT passé lors de l'établissement de la connexion ou dans le premier message.
  • Scalabilité : Les WebSockets gardent un état en mémoire. Utilisez un système Pub/Sub (comme Redis) pour synchroniser les messages entre plusieurs instances de serveurs.
  • Load Balancers : Vérifiez que votre équilibreur de charge supporte le protocole WebSocket et configurez les "sticky sessions" si nécessaire.

Optimisez votre flux de développement

Utilisez nos outils gratuits pour encoder, décoder et formater votre code en un clic.