W3docs

API WebSocket JavaScript

Apprenez l'API WebSocket JavaScript : cycle de vie, readyState, envoi de données texte, JSON et binaires, reconnexion, sécurité, avec un exemple de chat Echo interactif.

Introduction à la technologie WebSocket

WebSocket est un protocole qui fournit un canal de communication full-duplex (bidirectionnel) entre le navigateur et un serveur via une unique connexion TCP persistante. Une fois la connexion ouverte, chacune des deux parties peut envoyer un message à tout moment sans attendre que l'autre le demande — ce qu'HTTP ordinaire ne peut pas faire.

Cette page aborde ce que les WebSockets résolvent, le cycle de vie de la connexion, l'envoi de données texte et binaires, l'utilisation des messages JSON, la reconnexion, la sécurité, et quand utiliser une bibliothèque plutôt que l'API brute. Nous construisons tout autour d'un exemple de chat Echo interactif.

Pourquoi les WebSockets plutôt que HTTP ?

Avec HTTP classique (y compris l'API Fetch et XMLHttpRequest), le client doit initier chaque échange. Pour obtenir des mises à jour en temps réel, vous devez sonder — demander régulièrement « quelque chose de nouveau ? » — ce qui gaspille de la bande passante et augmente la latence. Les WebSockets renversent ce paradigme : le serveur peut pousser des données dès qu'il en a, avec presque aucun overhead par message.

ApprocheDirectionOverheadIdéal pour
Requête/réponse HTTPLe client demande, le serveur répondEn-têtes complets par requêteRequêtes ponctuelles, APIs REST
PollingLe client interroge selon un minuteurNombreuses requêtes inutilesMises à jour simples et peu fréquentes
WebSocketLes deux côtés poussent librementUne seule négociation, trames légèresChat, flux en direct, jeux, tableaux de bord

Utilisez les WebSockets lorsque le serveur doit parler en premier ou que les messages circulent en permanence : chat, jeux multijoueurs, éditeurs collaboratifs, cotations boursières et tableaux de bord en temps réel. Pour des mises à jour occasionnelles unidirectionnelles du serveur vers le client uniquement, les Server-Sent Events ou l'API Push peuvent être plus simples.

Le cycle de vie de la connexion WebSocket

Vous ouvrez une connexion en passant une URL ws:// (non chiffrée) ou wss:// (chiffrée) au constructeur WebSocket. La connexion passe ensuite par quatre états exposés par socket.readyState :

ConstanteValeurSignification
WebSocket.CONNECTING0Négociation en cours (état initial)
WebSocket.OPEN1Prêt à envoyer et recevoir
WebSocket.CLOSING2Une fermeture a été demandée
WebSocket.CLOSED3Connexion fermée ou échec d'ouverture

Vous réagissez aux transitions grâce à quatre événements : open, message, error et close. La règle clé est que vous ne pouvez appeler socket.send() que lorsque readyState vaut OPEN — envoyer avant le déclenchement de open lève une erreur.

const socket = new WebSocket("wss://echo.websocket.events");

socket.addEventListener("open", () => {
  console.log("open, readyState =", socket.readyState); // 1
  socket.send("hello");
});

socket.addEventListener("message", (event) => {
  console.log("received:", event.data); // "hello" (echoed back)
});

socket.addEventListener("close", (event) => {
  console.log("closed, code =", event.code); // e.g. 1000
});

Mise en place du chat Echo WebSocket

Structure HTML de base

Nous établissons d'abord l'interface utilisateur en HTML, comprenant une zone d'affichage des messages, un champ de saisie et des boutons de contrôle.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>WebSocket Echo Chat</title>
</head>
<body>
    <textarea id="chatBox" readonly style="width: 100%; height: 300px"></textarea><br />
    <input type="text" id="messageInput" placeholder="Type a message..." style="width: 75%" />
    <button onclick="sendMessage()">Send</button>
    <button onclick="closeConnection()">Close Connection</button>
</body>
</html>

Intégration de WebSocket avec JavaScript

Le JavaScript qui gère la communication WebSocket est essentiel pour activer les interactions en temps réel.

<script>
    // Accessing the chat box and message input elements from the HTML.
    const chatBox = document.getElementById("chatBox");
    const messageInput = document.getElementById("messageInput");

    // Establishing a WebSocket connection to the echo server.
    const socket = new WebSocket("wss://echo.websocket.events");

    // When the connection is open, display a connected message in the chat box.
    socket.addEventListener("open", function (event) {
        chatBox.value += "Connected to the echo server\n";
    });

    // Handle incoming messages by adding them to the chat box.
    socket.addEventListener("message", function (event) {
        chatBox.value += "Echoed back: " + event.data + "\n";
    });

    // Handle connection errors.
    socket.addEventListener("error", function (event) {
        chatBox.value += "Connection error occurred.\n";
    });

    // Handle connection closure.
    socket.addEventListener("close", function (event) {
        chatBox.value += "Connection closed. Code: " + event.code + "\n";
    });

    // Function to send a message when the send button is clicked.
    function sendMessage() {
        const message = messageInput.value; // Get the message from the input field.
        if (!message) return; // If there's no message, don't do anything.
        socket.send(message); // Send the message to the server.
        chatBox.value += "You: " + message + "\n"; // Show the message in the chat box.
        messageInput.value = ""; // Clear the message input field.
    }

    // Function to close the WebSocket connection.
    function closeConnection() {
        if (socket.readyState === WebSocket.OPEN) {
            socket.close(1000, "The user closed the connection"); // Close the connection normally.
            chatBox.value += "Connection closed by user\n"; // Inform the user in the chat box.
        } else {
            alert("Connection is not open or already closed."); // Alert if the connection can't be closed.
        }
    }

    // Ensure the WebSocket is closed properly when the webpage is closed or reloaded.
    window.addEventListener("beforeunload", function () {
        if (socket.readyState === WebSocket.OPEN) {
            socket.close(1000, "The page is unloading"); // Close the connection normally.
        }
    });
</script>

Ce script met en place une fonctionnalité de chat sur une page web qui se connecte à un serveur via WebSockets. Voici une explication simple de ses composants :

  1. Accès aux éléments HTML : Le script récupère la zone de chat et le champ de saisie de la page web afin d'interagir avec eux.
  2. Connexion WebSocket : Il ouvre une connexion vers un serveur qui renvoie les messages en écho. Cela signifie que tout ce que vous envoyez à ce serveur vous sera renvoyé immédiatement.
  3. Affichage du statut de connexion : Lorsque la connexion est établie avec succès, un message s'affiche dans la zone de chat indiquant que la connexion au serveur echo est établie.
  4. Gestion des messages entrants : Les messages renvoyés par le serveur sont ajoutés à la zone de chat, montrant que le serveur a bien renvoyé les messages.
  5. Envoi de messages : Une fonction permet d'envoyer les messages saisis dans le champ de saisie. S'il y a du texte, il est envoyé au serveur puis affiché dans la zone de chat comme votre message.
  6. Fermeture de la connexion : Une autre fonction permet de fermer la connexion WebSocket si nécessaire, par exemple lorsque l'utilisateur décide de la fermer ou lorsque la page web est en cours de fermeture.

Cette configuration permet une communication en temps réel avec le serveur et aide à tester et démontrer le fonctionnement des applications de messagerie.

Et maintenant, assemblons tout cela et voyons-le en action :

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>WebSocket Echo Chat</title>
  </head>

  <body>
    <textarea id="chatBox" readonly style="width: 100%; height: 300px">
    </textarea>
    <br />
    <input
      type="text"
      id="messageInput"
      placeholder="Type a message..."
      style="width: 75%"
    />
    <button onclick="sendMessage()">Send</button>
    <button onclick="closeConnection()">Close Connection</button>
  </body>
  <script>
    const chatBox = document.getElementById("chatBox");
    const messageInput = document.getElementById("messageInput");

    const socket = new WebSocket("wss://echo.websocket.events");

    socket.addEventListener("open", function (event) {
      chatBox.value += "Connected to the echo server\n";
    });

    socket.addEventListener("message", function (event) {
      chatBox.value += "Echoed back: " + event.data + "\n";
    });

    socket.addEventListener("error", function (event) {
      chatBox.value += "Connection error occurred.\n";
    });

    socket.addEventListener("close", function (event) {
      chatBox.value += "Connection closed. Code: " + event.code + "\n";
    });

    function sendMessage() {
      const message = messageInput.value;
      if (!message) return;
      socket.send(message);
      chatBox.value += "You: " + message + "\n";
      messageInput.value = "";
    }

    function closeConnection() {
      if (socket.readyState === WebSocket.OPEN) {
        socket.close(1000, "The user closed the connection");
        chatBox.value += "Connection closed by user\n";
      } else {
        alert("Connection not open or already closed.");
      }
    }

    window.addEventListener("beforeunload", function () {
      if (socket.readyState === WebSocket.OPEN) {
        socket.close(1000, "The page is unloading");
      }
    });
  </script>
</html>

Dans l'exemple ci-dessus, dès que vous vous connectez au serveur, vous pouvez commencer à envoyer des messages et vous recevrez exactement ce que vous avez tapé, renvoyé en écho. Si vous cliquez sur le bouton 'Close Connection', la connexion WebSocket sera interrompue et vous ne recevrez plus de messages en écho.

Fonctionnalités et techniques WebSocket avancées

Envoi de données structurées en JSON

Les applications réelles envoient rarement des chaînes simples — elles envoient des objects. Comme le canal ne transporte que du texte ou du binaire, vous sérialisez les objects avec JSON.stringify() avant l'envoi et les désérialisez avec JSON.parse() à la réception. Consultez Travailler avec JSON pour en savoir plus sur ce format.

// Sending an object
const payload = { type: "chat", user: "Ann", text: "Hi!" };
socket.send(JSON.stringify(payload));

// Receiving and parsing it
socket.addEventListener("message", (event) => {
  const msg = JSON.parse(event.data);
  console.log(msg.user + ": " + msg.text); // "Ann: Hi!"
});

Un pattern courant consiste à utiliser un champ type qui permet à une seule connexion de multiplexer différents types de messages — chat, presence, typing, etc. — chacun géré par sa propre branche.

Gestion des données binaires

Les WebSockets ne sont pas limités au texte. Ils peuvent également transporter des trames binaires, utiles pour l'audio, les images ou l'état de jeu. Définissez socket.binaryType pour contrôler la façon dont les données binaires entrantes arrivent — "blob" (par défaut) ou "arraybuffer".

socket.binaryType = "arraybuffer";

// Send raw bytes
const bytes = new Uint8Array([72, 73]); // "HI"
socket.send(bytes);

socket.addEventListener("message", (event) => {
  if (typeof event.data === "string") {
    console.log("text frame:", event.data);
  } else {
    const view = new Uint8Array(event.data);
    console.log("binary frame, length:", view.length);
  }
});

Reconnexion automatique

Les réseaux tombent. Le WebSocket brut ne se reconnecte pas automatiquement — lorsque close se déclenche de façon inattendue, vous devez rouvrir la connexion vous-même, idéalement avec un délai croissant (exponentiel) pour ne pas surcharger le serveur.

let delay = 1000; // start at 1 second

function connect() {
  const socket = new WebSocket("wss://echo.websocket.events");

  socket.addEventListener("open", () => {
    delay = 1000; // reset back-off after a successful connection
  });

  socket.addEventListener("close", () => {
    setTimeout(connect, delay);
    delay = Math.min(delay * 2, 30000); // cap at 30 seconds
  });
}

connect();

Mise en œuvre de la sécurité WebSocket

La sécurité est primordiale lorsqu'on travaille avec les WebSockets :

  • Utilisez WSS : Utilisez toujours WebSocket Secure (WSS), qui chiffre les données transmises entre le client et le serveur.
  • Authentification : Mettez en place une authentification par jeton pour garantir que seuls les utilisateurs autorisés peuvent établir des connexions WebSocket.
  • Validation : Validez correctement toutes les données envoyées au serveur pour prévenir les vulnérabilités web courantes telles que les injections XSS ou SQL.

WebSocket et le pattern Pub/Sub

Le pattern publish/subscribe est un modèle populaire dans les services de données en temps réel où les messages sont diffusés via un canal. Les services WebSocket comme PubNub proposent des APIs qui supportent le modèle pub/sub, améliorant les capacités des WebSockets en gérant les connexions, en assurant le chiffrement des données et en facilitant la diffusion par canal.

Bibliothèques et frameworks WebSocket

Plusieurs bibliothèques JavaScript facilitent et renforcent le travail avec les WebSockets :

  • Socket.IO : Fournit des fonctionnalités supplémentaires telles que la reconnexion automatique, la gestion des événements et la gestion des salles.
  • WebSocket-Node : Une implémentation de serveur WebSocket pour Node.js.
  • ReconnectingWebSocket : Une petite bibliothèque qui ajoute des fonctionnalités de reconnexion aux WebSockets natifs.

Conclusion

La technologie WebSocket est un bloc de construction fondamental pour le développement d'applications web interactives et en temps réel. En intégrant les WebSockets dans vos applications, vous activez une interaction directe et bidirectionnelle entre les clients et les serveurs. Ce guide a abordé le cycle de vie de la connexion, l'exemple de chat Echo, les messages JSON et binaires, la reconnexion et la sécurité — suffisamment pour construire des fonctionnalités temps réel robustes.

Voir aussi

  • API Fetch — pour les requêtes HTTP ponctuelles lorsque vous n'avez pas besoin d'un canal permanent.
  • XMLHttpRequest — l'ancienne API de requête sur laquelle les WebSockets et Fetch s'appuient conceptuellement.
  • API Push — messages du serveur vers le client même lorsque la page est fermée.
  • Travailler avec JSON — le format standard pour les messages WebSocket structurés.

Pratique

Pratique
Quels sont les principaux avantages de l'utilisation des WebSockets dans les applications web ?
Quels sont les principaux avantages de l'utilisation des WebSockets dans les applications web ?
Pratique
Dans quel readyState peut-on appeler socket.send() en toute sécurité ?
Dans quel readyState peut-on appeler socket.send() en toute sécurité ?
Pratique
Comment envoyer un object JavaScript via un WebSocket ?
Comment envoyer un object JavaScript via un WebSocket ?
Was this page helpful?