WebSocket en Node.js : serveur, client, heartbeat et reconnexion

WebSocket en Node.js : serveur ws, client intégré, heartbeat | We.Inc

Créez un serveur WebSocket en Node.js avec le paquet ws, connectez-vous avec le client WebSocket intégré de Node, détectez les sockets morts avec ping et pong, et reconnectez-vous avec un backoff.

Node.js n'a pas de serveur WebSocket intégré, donc la plupart des projets installent le paquet ws et créent un WebSocketServer. Côté client, Node fournit un WebSocket global compatible avec celui des navigateurs, ajouté dans v21.0.0 et v20.10.0, sans flag depuis v22.0.0 et marqué stable dans v22.4.0. Ajoutez un heartbeat ping et pong ainsi qu'une reconnexion avec backoff avant la mise en production.

Quel élément fait quoi

Ce guide construit un petit serveur de type chat et les clients qui lui parlent, dans l'ordre : un serveur qui renvoie et diffuse les messages, un script Node qui se connecte sans aucune dépendance, un heartbeat qui élimine les connexions mortes sans bruit, et un client qui revient après un redémarrage du serveur. Le calculateur ci-dessous montre comment vos délais de nouvelle tentative augmentent avant de les mettre dans le code.

Questions fréquentes

Node.js intègre-t-il WebSocket ?

Seulement le client. La classe globale WebSocket est apparue dans v21.0.0 et v20.10.0 derrière le flag --experimental-websocket, a perdu ce flag dans v22.0.0 et n'est plus expérimentale depuis v22.4.0. Il n'y a toujours pas de serveur intégré, c'est pourquoi ws reste le choix habituel.

Faut-il utiliser ws ou Socket.IO ?

ws parle le protocole WebSocket standard, donc n'importe quel client standard, y compris le navigateur et le global de Node, peut se connecter. Socket.IO ajoute son propre protocole par-dessus, avec des rooms et la reconnexion automatique, mais nécessite sa propre bibliothèque client de l'autre côté.

Pourquoi des connexions meurent-elles sans événement close ?

Si un chemin réseau disparaît, par exemple quand on ferme l'écran d'un portable, aucune trame de fermeture n'est envoyée et le serveur garde un socket à moitié ouvert. Le heartbeat les repère : un socket qui n'a pas répondu au dernier ping est terminé au tour suivant.

Un client navigateur peut-il envoyer des pings ?

Non. L'API du navigateur n'a que send() et close(). Les navigateurs répondent d'eux-mêmes aux pings du serveur par des pongs, c'est pourquoi le heartbeat côté serveur fonctionne aussi avec les clients navigateur.

Comment partager un port avec un serveur HTTP ?

Créez vous-même le serveur HTTP, par exemple avec Express ou node:http, puis passez-le avec new WebSocketServer({ server }). Les requêtes Upgrade vont à ws et les requêtes normales à votre application.

Comment démarre une connexion

Le heartbeat en termes simples

Se reconnecter sans marteler le serveur

Étape 1 : un serveur avec ws

server.js : écho et diffusion

Chaque message est renvoyé à tous les clients ouverts. Le listener error empêche un socket défaillant de faire planter le processus.

Étape 2 : un client sans dépendance

client.js : le WebSocket global de Node

Fonctionne sans modification sur Node 22 ou plus récent et dans une console de navigateur, car les deux exposent la même classe WebSocket.

Étape 3 : éliminer les connexions mortes avec ping et pong

Notre version du modèle du README de ws : marquer comme vivant au pong, terminer tout ce qui a manqué le dernier tour.

Étape 4 : un client qui se reconnecte

reconnect.js : backoff exponentiel avec jitter

Le délai double après chaque tentative échouée jusqu'à un plafond, reçoit une dispersion aléatoire, et revient à zéro dès qu'une connexion s'ouvre.

Derrière nginx

nginx ne transmet l'upgrade que si vous transférez vous-même les en-têtes Upgrade et Connection. Avant nginx 1.29.7, il faut aussi proxy_http_version 1.1.

Location nginx pour le socket

proxy_read_timeout relève la limite d'inactivité de 60 secondes ; le heartbeat ci-dessus maintient de toute façon le trafic.

Calculateur de délai de reconnexion

Définissez un premier délai, un multiplicateur et un plafond pour voir combien de temps un client attend avant chaque nouvelle tentative, ainsi que l'attente la plus courte et la plus longue une fois le jitter ajouté.

Premier délai (ms)

Multiplicateur

Plafond (ms)

Tentatives à afficher

Ajouter du jitter (attendre entre la moitié et la totalité du délai)

Attente avant chaque tentative de reconnexion

Tentative

Délai

Avec jitter

Attente totale jusqu'ici

{n} à {v} s

Les mêmes réglages en code

Commencer gratuitement · Sans carte bancaire

Voir aussi: Guides

Produit

Pour qui

Fonctionnalités

Ressources

Entreprise

Plan du site