Le protocole WebSocket permet de créer des applications web prenant en charge la communication bidirectionnelle en temps réel entre les clients et les serveurs. Intégré à HTML5, WebSocket facilite considérablement le développement de ce type d’applications par rapport aux méthodes disponibles auparavant. La plupart des navigateurs modernes prennent en charge WebSocket, notamment Chrome, Firefox, Internet Explorer, Opera et Safari, et de plus en plus de frameworks d’applications serveur le prennent également en charge.
Pour une utilisation en production en entreprise, où plusieurs serveurs WebSocket sont nécessaires pour garantir les performances et la haute disponibilité, une couche de répartition de charge prenant en charge le protocole WebSocket est indispensable. NGINX prend en charge WebSocket depuis la version 1.3 et peut faire office de proxy inverse et assurer la répartition de charge des applications WebSocket. (Toutes les versions de NGINX Plus prennent également en charge WebSocket.)
Consultez les récents tests de performance sur la capacité de NGINX à répartir la charge des connexions WebSocket.
Le protocole WebSocket est différent du protocole HTTP, mais la négociation WebSocket est compatible avec HTTP et utilise le mécanisme de mise à niveau HTTP pour faire passer la connexion de HTTP à WebSocket. Les applications WebSocket peuvent ainsi s’intégrer plus facilement aux infrastructures existantes. Par exemple, elles peuvent utiliser les ports HTTP standard 80 et 443, ce qui permet de conserver les règles de pare-feu existantes.
Une application WebSocket maintient ouverte une connexion de longue durée entre le client et le serveur, ce qui facilite le développement d’applications en temps réel. Le mécanisme HTTP Upgrade utilisé pour faire passer la connexion de HTTP à WebSocket utilise les en-têtes Upgrade et Connection. La prise en charge de WebSocket présente certaines difficultés pour un serveur proxy inverse. WebSocket étant un protocole de proche en proche, lorsqu’un serveur proxy intercepte une requête Upgrade provenant d’un client, il doit envoyer sa propre requête Upgrade au serveur backend, en y incluant les en-têtes appropriés. En outre, les connexions WebSocket étant de longue durée, contrairement aux connexions généralement de courte durée utilisées par HTTP, le proxy inverse doit permettre à ces connexions de rester ouvertes au lieu de les fermer parce qu’elles semblent inactives.
NGINX prend en charge WebSocket en permettant d’établir un tunnel entre un client et un serveur backend. Pour que NGINX transmette la requête de mise à niveau du client au serveur backend, les en-têtes Upgrade et Connection doivent être définis explicitement, comme dans cet exemple :
location /wsapp/ { proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}Une fois cette opération effectuée, NGINX traite la connexion comme une connexion WebSocket.
Exemple de WebSocket avec NGINX
Voici un exemple concret illustrant le fonctionnement de NGINX en tant que proxy WebSocket. Cet exemple utilise ws, une implémentation de WebSocket basée sur Node.js. NGINX fait office de proxy inverse pour une application WebSocket simple utilisant ws et Node.js. Ces instructions ont été testées avec Ubuntu 13.10 et CentOS 6.5, mais peuvent nécessiter des ajustements pour d’autres systèmes d’exploitation et versions. Dans cet exemple, l’adresse IP du serveur WebSocket est 192.168.100.10 et celle du serveur NGINX est 192.168.100.20.
- Si Node.js et npm ne sont pas encore installés, exécutez la commande suivante :
- Pour Debian et Ubuntu :
$ sudo apt-get install nodejs npm- Pour RHEL et CentOS :
$ sudo yum install nodejs npm- Node.js est installé sous le nom de «
nodejs» sur Ubuntu et de «node» sur CentOS. L’exemple utilise «node». Sur Ubuntu, nous devons donc créer un lien symbolique de «nodejs» vers «node» :
$ ln -s /usr/bin/nodejs /usr/local/bin/node- Pour installer ws, exécutez la commande suivante :
$ sudo npm install ws- Remarque : Si le message d’erreur « Error: failed to fetch from registry: ws » s’affiche, exécutez la commande suivante pour résoudre le problème :
$ sudo npm config set registry http://registry.npmjs.org/- Exécutez ensuite à nouveau la commande «
sudo npm install ws». - ws est fourni avec le programme /root/node_modules/ws/bin/wscat que nous utiliserons pour notre client, mais nous devons créer un programme qui fera office de serveur. Créez un fichier nommé server.js avec le contenu suivant :
console.log("Server started");
var Msg = '';
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({port: 8010});
wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log('Received from client: %s', message);
ws.send('Server received from client: ' + message);
});
});- Pour exécuter le programme serveur, lancez la commande suivante :
$ node server.js- Le serveur affiche d’abord le message
« Serverstarted », puis écoute sur le port 8010 en attendant qu’un client s’y connecte. Lorsqu’il reçoit une requête d’un client, il la renvoie en écho et retourne au client un message contenant celui qu’il a reçu. Pour que NGINX transmette ces requêtes en tant que proxy, nous créons la configuration suivante. Nous ajoutons le blocmapafin que l’en-têteConnectionsoit correctement défini surcloselorsque l’en-têteUpgradede la requête est défini sur''.
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 192.168.100.10:8010;
}
server {
listen 8020;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
}
}
}- NGINX écoute sur le port 8020 et transmet les requêtes au serveur WebSocket principal. Les directives «
proxy_set_header» permettent à NGINX de gérer correctement le protocole WebSocket. - Pour tester le serveur, nous exécutons « wscat » en tant que client :
$ /root/node_modules/ws/bin/wscat --connect ws://192.168.100.20:8020- wscat se connecte au serveur WebSocket via le proxy NGINX. Lorsque vous saisissez un message que wscat doit envoyer au serveur, vous le voyez s’afficher sur le serveur, puis un message du serveur apparaît sur le client. Voici un exemple d’interaction : Serveur : Client :
$node server.jsServeur démarré
wscat --connect ws://192.168.100.20:8020
Connecté (appuyez sur CTRL+C pour quitter)
> BonjourReçu du client : Bonjour< Le serveur a reçu du client : BonjourNous voyons ici que le client et le serveur peuvent communiquer via NGINX, qui fait office de proxy, et que les messages peuvent continuer à être échangés jusqu’à ce que le client ou le serveur se déconnecte. Pour que NGINX gère correctement WebSocket, il suffit de configurer correctement les en-têtes afin de traiter la requête Upgrade, qui fait passer la connexion de HTTP à WebSocket.
Pour aller plus loin
- Proxy inverse WebSocket sur nginx.org
- Comparaison des fonctionnalités de NGINX et NGINX Plus
- Spécifications techniques de NGINX Plus
- Configuration du proxy pour le trafic WebSocket dans :
- Répartition de charge des serveurs Apache Tomcat avec NGINX Open Source et NGINX Plus
- Répartition de charge des serveurs d’applications Node.js avec NGINX Open Source et NGINX Plus
- Répartition de charge d’Oracle WebLogic Server avec NGINX Open Source et NGINX Plus
- Équilibrage de charge des serveurs d’applications WildFly et JBoss avec NGINX Open Source et NGINX Plus
À propos de l’auteur

Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.
Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.
Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.
Caches partagés avec les clusters de cache NGINX Plus, partie 1
Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.
Introduction aux microservices
Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.