
Dans une application de chat, un tableau de bord en temps réel ou un jeu en ligne, les données doivent circuler sans attendre qu’un navigateur relance sans cesse des requêtes. C’est précisément là qu’intervient WebSocket. Avant que cette communication continue puisse commencer, client et serveur passent par une étape discrète mais essentielle : le handshake WebSocket.
Le handshake WebSocket est la phase d’ouverture qui permet à un navigateur ou à une application cliente de demander à un serveur de transformer une connexion HTTP classique en connexion WebSocket. Le terme “handshake”, ou poignée de main, désigne cet échange initial de messages qui sert à vérifier que les deux parties parlent bien le même protocole.
Concrètement, tout commence par une requête HTTP, généralement en HTTP/1.1. Le client demande une mise à niveau de la connexion grâce à l’en-tête Upgrade: websocket. Si le serveur accepte, il répond avec le code 101 Switching Protocols. À partir de cet instant, la connexion n’est plus utilisée comme une requête-réponse HTTP traditionnelle : elle devient un canal bidirectionnel persistant.
Le protocole WebSocket a été conçu pour résoudre une limite historique du web : HTTP fonctionne principalement sur un modèle où le client interroge le serveur. Pour recevoir une nouvelle information, il fallait souvent répéter les requêtes, utiliser du long polling ou maintenir des mécanismes coûteux. WebSocket permet au serveur d’envoyer des données dès qu’elles sont disponibles.
Mais cette transition ne peut pas se faire brutalement. Le handshake garantit que le serveur accepte explicitement le changement de protocole et que les intermédiaires réseau, comme les proxys, comprennent au moins le début de l’échange. Cette logique s’inscrit dans l’écosystème HTTP, où les codes de réponse jouent un rôle central ; à titre de comparaison, certains codes comme le statut HTTP 451 signalent des situations très différentes, liées à des restrictions légales.
Le client envoie d’abord une requête GET vers une adresse commençant par ws:// ou wss://. Cette requête contient plusieurs en-têtes obligatoires. Les plus importants sont Connection: Upgrade, Upgrade: websocket, Sec-WebSocket-Version: 13 et Sec-WebSocket-Key. Ce dernier est une valeur aléatoire encodée en Base64, générée par le client pour cette tentative de connexion.
Le serveur vérifie ensuite la demande. S’il prend en charge WebSocket et autorise la connexion, il renvoie une réponse HTTP 101. Cette réponse contient l’en-tête Sec-WebSocket-Accept, calculé à partir de la clé envoyée par le client. Le calcul repose sur une concaténation avec un identifiant fixe défini par la norme, puis sur un hachage SHA-1 et un encodage Base64. Ce mécanisme ne chiffre pas la connexion, mais il confirme que le serveur a bien compris la demande WebSocket.
Une fois la réponse 101 reçue et validée, la connexion TCP existante reste ouverte. Elle n’est plus utilisée pour transporter des messages HTTP ordinaires, mais des trames WebSocket. Ces trames peuvent contenir du texte, des données binaires, des messages de contrôle ou des signaux de fermeture.
L’intérêt est majeur : le client et le serveur peuvent désormais écrire chacun de leur côté, sans attendre une nouvelle requête. Dans un service de messagerie, par exemple, le serveur peut pousser immédiatement un nouveau message vers le navigateur. Dans une plateforme de suivi logistique, une position GPS peut être transmise dès qu’elle change. Le handshake n’est donc qu’une courte étape, mais il ouvre la voie à une communication continue.
Une adresse WebSocket peut commencer par ws:// ou par wss://. La première correspond à une connexion non chiffrée, comparable à HTTP. La seconde repose sur TLS, comme HTTPS, et permet de protéger les données contre l’écoute et l’altération pendant le transport. En pratique, wss:// est indispensable pour les services exposés sur Internet.
Avec wss://, la négociation TLS a lieu avant le handshake WebSocket. Le client vérifie le certificat du serveur, établit un canal chiffré, puis envoie la requête de mise à niveau à l’intérieur de ce tunnel sécurisé. Cette distinction rappelle l’importance de la conception des protocoles : contrairement à WebSocket sécurisé, certains protocoles anciens comme FTP ont été conçus sans chiffrement natif, ce qui explique les limites de sécurité de FTP par défaut.
Le handshake WebSocket peut aussi transporter des éléments d’authentification. Dans un navigateur, les cookies associés au domaine sont souvent envoyés automatiquement, comme dans une requête HTTP classique. Une application peut également transmettre un jeton dans l’URL ou dans un en-tête lorsque l’environnement technique le permet.
Cette souplesse impose de la prudence. Le serveur doit vérifier l’identité de l’utilisateur, mais aussi l’en-tête Origin, qui indique l’origine de la page ayant initié la connexion. Sans contrôle strict, un site tiers pourrait tenter d’ouvrir une connexion WebSocket vers un service où l’utilisateur est déjà authentifié. La logique de confiance par preuve cryptographique existe aussi dans d’autres domaines du web, comme l’authentification DKIM des emails, même si les mécanismes et les objectifs sont différents.
Dans un réseau réel, le client ne parle pas toujours directement au serveur applicatif. La connexion peut traverser un proxy, un pare-feu, un équilibreur de charge ou un CDN. Ces intermédiaires doivent accepter l’en-tête Upgrade et laisser la connexion ouverte. Une mauvaise configuration peut provoquer des coupures, des délais d’inactivité trop courts ou des erreurs difficiles à diagnostiquer.
Avant même le handshake, le client doit résoudre le nom de domaine du service WebSocket. Cette étape DNS peut influencer la confidentialité et les performances perçues. Les mécanismes modernes comme la résolution DNS chiffrée via HTTPS montrent que la sécurité d’une connexion ne se limite pas au protocole applicatif : elle dépend aussi de toute la chaîne réseau.
Le handshake WebSocket classique repose historiquement sur HTTP/1.1. Des extensions existent toutefois pour HTTP/2, notamment via le mécanisme Extended CONNECT défini par la RFC 8441. Avec HTTP/3, l’écosystème évolue encore, porté par QUIC, un protocole de transport au-dessus d’UDP. Pour comprendre cette mutation, le fonctionnement de QUIC avec HTTP/3 éclaire les changements en matière de latence, de multiplexage et de reprise de connexion.
Dans la pratique, les fondamentaux restent les mêmes : vérifier l’origine, utiliser wss://, limiter les durées d’inactivité, surveiller les erreurs de handshake et documenter les codes de fermeture. Le handshake WebSocket est court, mais il concentre plusieurs enjeux : compatibilité HTTP, sécurité, authentification et stabilité réseau. Bien compris, il devient un outil fiable pour construire des applications réellement interactives, sans multiplier les requêtes inutiles.