HTML - WebSocket

-

Concepts de base

WebSocket est un protocole de communication qui fournit des canaux de communication full-duplex sur une seule connexion TCP. Il permet une communication bidirectionnelle en temps réel entre un client (généralement un navigateur web) et un serveur. Le protocole WebSocket est conçu pour être utilisé dans les navigateurs web et les serveurs, mais il peut également être utilisé par n'importe quelle application client ou serveur.

L'une des principales caractéristiques de WebSocket est sa capacité de communication full-duplex. Contrairement aux requêtes HTTP traditionnelles, où le client envoie une requête et attend une réponse du serveur, WebSocket permet au client et au serveur d'envoyer des messages l'un à l'autre indépendamment à tout moment. Cela permet un transfert de données en temps réel sans que le client n'ait besoin de demander régulièrement des mises à jour au serveur.

Le protocole WebSocket diffère du HTTP de plusieurs manières. Alors que HTTP est un protocole de requête-réponse, WebSocket est un protocole avec état qui maintient une connexion persistante entre le client et le serveur. Les connexions HTTP sont fermées après chaque cycle de requête-réponse, tandis que les connexions WebSocket restent ouvertes, permettant une communication continue. De plus, WebSocket utilise un schéma d'URI différent (ws:// pour les connexions non chiffrées et wss:// pour les connexions chiffrées) par rapport aux http:// et https:// de HTTP.

Pour établir une connexion WebSocket, le client envoie une requête HTTP au serveur avec un en-tête Upgrade, indiquant le souhait de passer au protocole WebSocket. Si le serveur prend en charge WebSocket, il répond avec un en-tête Upgrade spécifique, et la connexion passe de HTTP à WebSocket. Une fois la connexion établie, le client et le serveur peuvent s'envoyer des messages en utilisant le protocole WebSocket.

Le schéma d'URI WebSocket est utilisé pour identifier les connexions WebSocket. Il se compose du préfixe ws:// pour les connexions non chiffrées et wss:// pour les connexions chiffrées (similaire à https://). L'URI WebSocket suit un format spécifique :

Conseil: Format d'URI WebSocket

ws://host:port/path

Où :

  • host est le nom de domaine ou l'adresse IP du serveur
  • port est le numéro de port (par défaut 80 pour ws:// et 443 pour wss://)
  • path est un composant de chemin optionnel
Caractéristique WebSocket HTTP
Communication Full-duplex Requête-réponse
Connexion Persistante Fermée après chaque cycle requête-réponse
Schéma d'URI ws:// et wss:// http:// et https://

WebSocket offre un moyen efficace et flexible de communication en temps réel entre les clients et les serveurs par rapport au HTTP traditionnel. Sa nature full-duplex, ses connexions persistantes et son schéma d'URI dédié en font un choix adapté pour la création d'applications web réactives et interactives.

API WebSocket

L'API WebSocket permet aux navigateurs web de communiquer avec un serveur WebSocket en utilisant JavaScript. Elle permet de créer un objet WebSocket, de se connecter à un serveur, d'envoyer et de recevoir des messages, et de gérer différents événements WebSocket.

Pour créer un objet WebSocket, utilisez le constructeur WebSocket, qui prend l'URL du serveur WebSocket comme paramètre :

Conseil: Créer un objet WebSocket

const socket = new WebSocket('ws://example.com/ws');

Une fois l'objet WebSocket créé, vous pouvez établir une connexion au serveur WebSocket en utilisant la méthode connect(). Cependant, la connexion démarre automatiquement lors de la création de l'objet WebSocket, il n'est donc pas nécessaire d'appeler directement connect().

Après l'établissement de la connexion, vous pouvez envoyer des messages au serveur en utilisant la méthode send() de l'objet WebSocket. Le message peut être une chaîne de caractères, un ArrayBuffer ou un Blob :

Conseil: Envoyer un message au serveur WebSocket

socket.send('Bonjour, serveur WebSocket !');

Pour recevoir des messages du serveur, vous devez écouter l'événement onmessage. Cet événement est déclenché chaque fois qu'un message est reçu du serveur. Vous pouvez accéder au message reçu via la propriété data de l'objet événement :

Conseil: Recevoir des messages du serveur

socket.onmessage = function(event) {
  console.log('Message reçu :', event.data);
};

Lorsque vous avez terminé avec la connexion WebSocket, vous pouvez la fermer en utilisant la méthode close() :

Conseil: Fermer la connexion WebSocket

socket.close();

L'API WebSocket fournit plusieurs événements que vous pouvez écouter pour gérer différentes étapes de la connexion :

Événement Description
onopen Déclenché lorsque la connexion WebSocket est établie avec succès.
onmessage Déclenché lorsqu'un message est reçu du serveur.
onerror Déclenché lorsqu'une erreur survient avec la connexion WebSocket.
onclose Déclenché lorsque la connexion WebSocket est fermée.

Conseil: Gérer les événements WebSocket

socket.onopen = function(event) {
  console.log('Connexion WebSocket ouverte');
};

socket.onmessage = function(event) {
  console.log('Message reçu :', event.data);
};

socket.onerror = function(event) {
  console.error('Erreur WebSocket survenue :', event);
};

socket.onclose = function(event) {
  console.log('Connexion WebSocket fermée');
};

En utilisant l'API WebSocket, vous pouvez créer des applications web interactives qui communiquent avec un serveur en temps réel. Vous pouvez envoyer des messages au serveur, recevoir des messages du serveur et gérer différents événements de connexion pour créer des expériences utilisateur réactives et dynamiques.

Implémentation côté serveur

Pour utiliser WebSocket dans votre application web, vous avez besoin d'un serveur qui prend en charge le protocole WebSocket. L'implémentation côté serveur de WebSocket implique la gestion de la poignée de main WebSocket, la gestion des connexions et l'échange de messages avec les clients connectés.

Exigences du serveur WebSocket
Prise en charge du protocole WebSocket (RFC 6455)
Capacité à gérer la poignée de main WebSocket et à mettre à niveau la connexion de HTTP à WebSocket
Capacité à maintenir des connexions persistantes avec plusieurs clients
Capacité à envoyer et recevoir des messages de manière asynchrone

Plusieurs langages de programmation et frameworks populaires fournissent des bibliothèques et des outils pour implémenter des serveurs WebSocket. Voici quelques bibliothèques WebSocket côté serveur largement utilisées :

Node.js :

  • Socket.IO : Une bibliothèque puissante qui permet une communication en temps réel, bidirectionnelle et basée sur les événements entre le navigateur et le serveur. Elle fournit une abstraction de plus haut niveau sur WebSocket et offre des fonctionnalités supplémentaires comme la reconnexion automatique et le multiplexage.
  • ws : Une bibliothèque WebSocket simple et légère pour Node.js. Elle se concentre sur la fourniture d'une implémentation WebSocket pure sans abstractions ou fonctionnalités supplémentaires.

Python :

  • Flask-SocketIO : Une extension pour le framework web Flask qui ajoute le support de WebSocket et permet une communication en temps réel entre les clients et le serveur. Elle s'intègre avec la bibliothèque Socket.IO populaire et fournit une API conviviale pour gérer les événements WebSocket.
  • Tornado : Un framework web évolutif et non bloquant et une bibliothèque de réseau asynchrone pour Python. Il inclut un support intégré pour WebSocket et permet de gérer efficacement les connexions WebSocket.

Java :

  • Java-WebSocket : Une bibliothèque Java qui fournit une implémentation de serveur et de client WebSocket. Elle suit la spécification du protocole WebSocket et offre une API simple et intuitive pour construire des applications WebSocket.
  • Jetty : Un serveur web Java populaire et un conteneur de servlets qui inclut le support de WebSocket. Il fournit une API WebSocket et permet d'intégrer des fonctionnalités WebSocket dans les applications web Java.

Pour configurer un serveur WebSocket de base, vous devez choisir une technologie côté serveur et une bibliothèque qui correspondent à vos exigences et à vos préférences en matière de langage de programmation.

Conseil: Configuration d'un serveur WebSocket avec Node.js et la bibliothèque 'ws'

const WebSocket = require('ws');

const server = new WebSocket.Server({ port: 8080 });

server.on('connection', (socket) => {
  console.log('Client connecté');

  socket.on('message', (message) => {
    console.log(`Message reçu : ${message}`);
    socket.send(`Le serveur a reçu : ${message}`);
  });

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

En implémentant un serveur WebSocket, vous pouvez gérer les connexions entrantes, recevoir des messages des clients et leur envoyer des messages en temps réel. Les détails spécifiques de l'implémentation peuvent varier en fonction de la technologie côté serveur et de la bibliothèque choisies, mais les principes généraux restent les mêmes.

N'oubliez pas de gérer les événements de connexion WebSocket, tels que connection, message et close, pour gérer correctement le cycle de vie des connexions WebSocket et répondre aux interactions des clients.

Implémentation côté client

Pour implémenter la communication WebSocket côté client, vous pouvez utiliser l'API WebSocket JavaScript. Cette API vous permet d'établir une connexion WebSocket, de gérer les événements, d'envoyer et de recevoir des messages, et de fermer la connexion.

Pour établir une connexion WebSocket, vous devez d'abord créer un nouvel objet WebSocket en fournissant l'URL du serveur WebSocket :

Conseil: Création d'une connexion WebSocket

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

Une fois l'objet WebSocket créé, vous pouvez gérer divers événements à l'aide des gestionnaires d'événements suivants :

Gestionnaire d'événements Description
onopen Déclenché lorsque la connexion WebSocket est établie.
onmessage Déclenché lorsqu'un message est reçu du serveur.
onerror Déclenché lorsqu'une erreur se produit avec la connexion WebSocket.
onclose Déclenché lorsque la connexion WebSocket est fermée.

Conseil: Gestion des événements WebSocket

socket.onopen = function(event) {
  console.log('Connexion WebSocket établie');
};

socket.onmessage = function(event) {
  console.log('Message reçu:', event.data);
};

socket.onerror = function(event) {
  console.error('Erreur WebSocket survenue:', event);
};

socket.onclose = function(event) {
  console.log('Connexion WebSocket fermée');
};

Pour envoyer des messages au serveur, vous pouvez utiliser la méthode send() de l'objet WebSocket. Le message peut être une chaîne de caractères, un ArrayBuffer ou un Blob :

Conseil: Envoi d'un message

socket.send('Bonjour, serveur WebSocket !');

Lorsque le serveur envoie un message au client, l'événement onmessage est déclenché, et vous pouvez accéder au message reçu via la propriété data de l'objet événement :

Conseil: Réception d'un message

socket.onmessage = function(event) {
  console.log('Message reçu:', event.data);
};

Pour fermer la connexion WebSocket, vous pouvez appeler la méthode close() sur l'objet WebSocket :

Conseil: Fermeture de la connexion WebSocket

socket.close();

Lorsque la connexion est fermée, soit par le client, soit par le serveur, l'événement onclose est déclenché, vous permettant d'effectuer tout nettoyage nécessaire ou de gérer la fermeture de la connexion.

Conseil: Exemple complet de client WebSocket

<!DOCTYPE html>
<html>
<head>
  <title>Exemple de client WebSocket</title>
</head>
<body>
  <script>
    const socket = new WebSocket('ws://localhost:8080');

    socket.onopen = function(event) {
      console.log('Connexion WebSocket établie');
      socket.send('Bonjour, serveur WebSocket !');
    };

    socket.onmessage = function(event) {
      console.log('Message reçu:', event.data);
    };

    socket.onerror = function(event) {
      console.error('Erreur WebSocket survenue:', event);
    };

    socket.onclose = function(event) {
      console.log('Connexion WebSocket fermée');
    };
  </script>
</body>
</html>

Sécurité WebSocket

Lors de l'utilisation de WebSocket pour la communication en temps réel, il est important de réfléchir à la sécurité pour protéger votre application et vos utilisateurs contre les vulnérabilités potentielles. WebSocket introduit certaines considérations de sécurité qui doivent être abordées.

L'un des mécanismes de sécurité de base dans WebSocket est le modèle de sécurité basé sur l'origine. Les serveurs WebSocket doivent vérifier l'origine des connexions entrantes pour s'assurer qu'elles proviennent de sources fiables. Les navigateurs envoient l'en-tête Origin pendant la négociation WebSocket, et les serveurs peuvent vérifier cet en-tête pour autoriser ou refuser les connexions en fonction de l'origine. Cela aide à prévenir l'accès non autorisé aux ressources WebSocket depuis différents domaines.

Pour améliorer davantage la sécurité, WebSocket prend en charge l'utilisation du protocole WebSocket sécurisé (wss://). Similaire à HTTPS, wss:// crypte la communication WebSocket en utilisant SSL/TLS. Cela protège les données envoyées entre le client et le serveur contre l'écoute clandestine et la falsification. Lors du traitement d'informations sensibles ou d'authentification, il est recommandé d'utiliser wss:// pour établir une connexion WebSocket sécurisée.

L'authentification et l'autorisation sont des aspects importants de la sécurité WebSocket. Les connexions WebSocket doivent être authentifiées pour s'assurer que seuls les utilisateurs autorisés peuvent accéder aux ressources WebSocket. Cela peut être fait en mettant en œuvre des mécanismes d'authentification tels que l'authentification basée sur des jetons ou l'authentification basée sur des sessions. Après une authentification réussie, le serveur peut associer la connexion WebSocket à l'utilisateur authentifié et effectuer des vérifications d'autorisation pour contrôler l'accès à des ressources ou actions spécifiques.

Le détournement de WebSocket inter-site (CSWSH) est une vulnérabilité de sécurité qui permet aux attaquants d'accéder aux connexions WebSocket depuis un domaine différent. Pour prévenir le CSWSH, les serveurs WebSocket doivent mettre en œuvre une validation d'origine appropriée et n'autoriser que les connexions provenant d'origines de confiance. L'utilisation de cookies sécurisés (avec les attributs Secure et HttpOnly) pour l'authentification peut aider à réduire le risque de vol de cookies et d'accès non autorisé aux connexions WebSocket.

Meilleures pratiques pour sécuriser les connexions WebSocket
Utiliser le protocole WebSocket sécurisé (wss://) pour une communication cryptée.
Valider l'en-tête Origin pour autoriser les connexions uniquement depuis des domaines de confiance.
Mettre en œuvre des mécanismes d'authentification et d'autorisation robustes.
Utiliser des cookies sécurisés pour l'authentification afin de prévenir le vol de cookies.
Valider et assainir les entrées utilisateur pour prévenir les attaques par injection.
Maintenir à jour les bibliothèques WebSocket et les logiciels serveur avec les derniers correctifs de sécurité.
Mettre en œuvre la limitation de débit et le contrôle des connexions pour se protéger contre les attaques par déni de service.
Surveiller et enregistrer l'activité WebSocket pour l'audit de sécurité et la réponse aux incidents.

Cas d'utilisation et exemples

WebSocket a une large gamme d'applications et de cas d'utilisation où la communication en temps réel est essentielle. Examinons quelques exemples courants où WebSocket excelle :

Applications de chat en temps réel : WebSocket convient parfaitement à la création d'applications de chat en temps réel. Avec WebSocket, vous pouvez créer des salons de discussion où plusieurs utilisateurs peuvent envoyer et recevoir des messages instantanément. Lorsqu'un utilisateur envoie un message, le serveur peut le diffuser à tous les clients connectés en temps réel, permettant une communication fluide et interactive. WebSocket permet des fonctionnalités telles que les indicateurs de frappe, la présence en ligne et la livraison de messages en temps réel, rendant les applications de chat réactives et engageantes.

Mises à jour en direct et notifications : WebSocket est idéal pour fournir des mises à jour en direct et des notifications aux utilisateurs.

Conseil: Exemple de mises à jour en direct

// Exemple côté serveur
wss.on('connection', function (ws) {
  ws.send('Bienvenue dans le service de notification en temps réel !');
});

Dans une application de médias sociaux, lorsqu'un utilisateur reçoit un nouveau message, un like ou un commentaire, le serveur peut envoyer une notification en temps réel au navigateur de l'utilisateur en utilisant WebSocket.

Cela permet des mises à jour instantanées sans avoir besoin d'actualiser manuellement la page. De même, sur un site d'actualités ou de sports, WebSocket peut être utilisé pour fournir des mises à jour en temps réel sur les dernières nouvelles, les scores ou les cours des actions, gardant les utilisateurs informés et engagés.

Édition collaborative et tableau blanc : WebSocket permet des applications d'édition collaborative et de tableau blanc où plusieurs utilisateurs peuvent travailler ensemble en temps réel.

Conseil: Exemple d'édition collaborative

socket.on('documentChange', function (data) {
  updateDocument(data);
});

Lorsqu'un utilisateur apporte des modifications à un document ou dessine sur un tableau blanc virtuel, le serveur peut instantanément envoyer ces modifications à tous les clients connectés.

Cela permet une collaboration fluide, car les utilisateurs peuvent voir les modifications des autres en temps réel. WebSocket fournit un canal de communication à faible latence, rendant l'édition collaborative fluide et réactive.

Jeux multijoueurs : WebSocket est largement utilisé dans les applications de jeux multijoueurs. Il permet une interaction en temps réel entre les joueurs, permettant des fonctionnalités comme les mouvements des joueurs, la synchronisation de l'état du jeu et le chat en jeu.

Conseil: Exemple de jeux multijoueurs

// Exemple de mouvement de joueur
socket.on('move', function (data) {
  updatePlayerPosition(data);
});

Les joueurs peuvent envoyer leurs actions au serveur, et le serveur peut diffuser l'état de jeu mis à jour à tous les joueurs connectés instantanément.

Cela crée une expérience de jeu réactive et immersive, car les joueurs peuvent voir les actions des autres et interagir en temps réel.

Visualisation de données en temps réel : WebSocket est utile pour les applications de visualisation de données en temps réel, telles que les tableaux de bord, les systèmes de surveillance ou les plateformes de trading financier.

Conseil: Exemple de visualisation de données en temps réel

// Exemple de mise à jour de données en temps réel
socket.on('dataUpdate', function (data) {
  updateChart(data);
});

Lorsque de nouvelles données deviennent disponibles sur le serveur, elles peuvent être instantanément transmises aux clients connectés en utilisant WebSocket.

Cela permet des mises à jour en temps réel de graphiques, de diagrammes et d'autres représentations visuelles sans nécessiter d'actualisations manuelles. WebSocket permet un flux de données fluide et continu, rendant les applications de visualisation de données plus dynamiques et interactives.

Ce ne sont que quelques exemples de la façon dont WebSocket peut être appliqué dans différents domaines. La nature en temps réel de la communication WebSocket ouvre des possibilités pour une large gamme d'applications interactives et engageantes. Qu'il s'agisse de permettre la messagerie instantanée, de fournir des mises à jour en direct, de faciliter la collaboration ou de créer des expériences de jeu immersives, WebSocket offre un outil puissant pour construire des applications web réactives et dynamiques. Voici la traduction en français du texte fourni :

Prise en charge des navigateurs et solution de repli

WebSocket est pris en charge par les navigateurs web modernes, notamment Google Chrome, Mozilla Firefox, Apple Safari, Microsoft Edge et Internet Explorer 11. Cependant, vous devez prendre en compte la prise en charge des navigateurs et prévoir des solutions de repli pour les navigateurs plus anciens qui pourraient ne pas prendre en charge WebSocket.

Pour vérifier si un navigateur prend en charge WebSocket, vous pouvez utiliser la propriété window.WebSocket. Si la propriété existe, cela signifie que le navigateur prend en charge WebSocket :

Conseil: Vérification de la prise en charge de WebSocket

if (window.WebSocket) {
  console.log('WebSocket est pris en charge');
  // Procéder à la connexion WebSocket
} else {
  console.log('WebSocket n'est pas pris en charge');
  // Solution de repli vers d'autres méthodes de communication
}

Si un navigateur ne prend pas en charge WebSocket, vous pouvez proposer des solutions de repli pour permettre une communication en temps réel en utilisant d'autres techniques. Voici deux approches courantes de repli :

Approche Description
Long-polling Le client envoie une requête au serveur et maintient la connexion ouverte jusqu'à ce que le serveur ait de nouvelles données à envoyer. Une fois que le serveur envoie les données, la connexion est fermée, et le client envoie immédiatement une autre requête au serveur, recommençant ainsi le processus. Cela crée une boucle continue de requêtes et de réponses, simulant une communication en temps réel.
Server-sent events (SSE) Les événements envoyés par le serveur permettent au serveur de pousser des données vers le client en utilisant une connexion unidirectionnelle. Le client établit une connexion avec le serveur en utilisant l'API EventSource, et le serveur peut envoyer des événements au client chaque fois que de nouvelles données sont disponibles. SSE est pris en charge par la plupart des navigateurs modernes et offre un moyen simple de recevoir des mises à jour en temps réel du serveur.

Lors de la mise en place de solutions de repli, vous devez envisager des stratégies de dégradation gracieuse. La dégradation gracieuse consiste à fournir une expérience de repli qui reste fonctionnelle et utilisable, même si elle peut ne pas avoir toutes les fonctionnalités ou les performances de l'implémentation principale basée sur WebSocket.

Conseil: Dégradation gracieuse avec options de repli

if (window.WebSocket) {
  // Établir la connexion WebSocket
  const socket = new WebSocket('ws://localhost:8080');
  // Code spécifique à WebSocket
} else if (window.EventSource) {
  // Repli vers les événements envoyés par le serveur
  const eventSource = new EventSource('/events');
  // Code spécifique aux événements envoyés par le serveur
} else {
  // Repli vers le long-polling
  setInterval(function() {
    // Envoyer une requête de long-polling au serveur
    // Traiter la réponse du serveur
  }, 5000);
}

En proposant des options de repli et en mettant en place une dégradation gracieuse, vous pouvez vous assurer que votre application fonctionne sur une plus large gamme de navigateurs et offre une expérience utilisable même en l'absence de prise en charge de WebSocket. Cependant, il convient de noter que les options de repli peuvent ne pas offrir le même niveau de performance et de réactivité que WebSocket, il est donc toujours recommandé d'utiliser WebSocket chaque fois que possible.