NodeJS - WebSockets avec Express
Cet article présentation l’implémentation d’un serveur et d’un client webSocket avec Node.js en utilisant la librairie express-ws.
Le code présenté est une version adaptée des exemples présentée sur le répertoire github de express-ws : HenningM - express-ws
Vous retrouverez l’ensemble du code sur mon répertoire github : rya-sge - nodeJS/websocket
Introduction
Fonctionnement
-
Le navigateur internet ouvre une connexion et upgrade le protocole à websocket
-
Une fois la connexion websocket ouverte, le navigateur et le serveur sont autorisées à envoyer des événements
-
Le navigateur fournit une WebScoket API qui gère le protocole upgrade
Cette méthode est caractérisé par une relative haute latence (TCP)
Installation
Installer les modules avec npm
npm install express
npm install express-ws
Server
Mise en place
Pour obtenir le serveur, il faut d’abord créer une application express puis ensuite l’utiliser pour monter express-ws dessus.
var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
app.listen(3000);
Middleware
Une fois que nous avons mis en place une application, on peut définir une fonction middleware de niveau application.
Celle-ci sera exécutée à chaque fois que l’application reçoit une demande
app.use(function (req, res, next) {
console.log('middleware');
req.testing = 'testing';
return next();
});
Source : expressjs.com - middleware
Route
On peut ensuite définir des routes afin de pouvoir y accéder par le navigateur. Dans l’exemple, j’ai défini des routes GET pour la racine ‘/’ ainsi que pour ‘/echo’
//Define a rout for /
app.get('/', function(req, res, next){
console.log('get route', req.testing);
res.end();
});
//Define a route for echo
app.get('/echo', function(req, res, next){
console.log('get route echo', req.testing);
res.end();
});
WebSocket
Il est ensuite possible de définir les “routes” pour les websockets. Comme plus haut, il y a une route pour la racine /'ainsi qu’une route pour /echo.
On peut ensuite définir des listeners qui attendre qu’un certains événements se produisent. Dans le cas présent, j’ai défini des listeners pour les événements message et close
La documentation de la classe WebScoket est disponible à l’adresse suivante : github.com - class-websocket
app.ws('/', function(ws, req) {
console.log('socket', req.testing);
ws.on('message', function(msg) {
console.log(msg);
});
ws.on('close', () => {
console.log('WebSocket was closed');
});
});
app.ws('/echo', (ws, req) => {
ws.on('message', msg => {
ws.send(msg);
});
ws.on('close', () => {
console.log('WebSocke echo was closed');
});
})
Source :
- stackoverflow.com - how-to-setup-route-for-websocket-server-in-express
- masteringjs.io/tutorials/express/websockets
Client
Mise en place
Pour déclarer un client, on importe le module wset on définit un nouveau websocket sur l’adresse de notre serveur :
const ws = require('ws');
const client = new ws('ws://localhost:3000');
Si on souhaite atteindre le websocket /echo plutôt que root il faudra alors l’indiquer dans l’url
const client = new ws('ws://localhost:3000/echo');
Evénements
On définit ensuite des listeners qui vont exécuter du code dès qu’un certains événements se produits
- Ouverture de la connexion
client.on('open', () => {
// Causes the server to print "Hello"
console.log("send message...")
client.send('Hello');
});
- Message reçu du serveur
client.on('message', function(msg) {
console.log("response from server : ", msg);
});
- Fermeture de la connexion
client.on('close', function(msg) {
console.log("response from server : ", msg);
});
Exemples
- Lancement du serveur
node server.js
- Lancement du client
$ node client.js
send message...
Open a connection
- Affichage sur le serveur
middleware
socket testing
Hello
-
Fermeture de la connexion par le client
WebSocket was closed
Sources
- Documentation officielle :
- Cours de Technologie Web (TWEB) enseigné à l’HEIG-VD en 2021
- stackoverflow.com - how-to-setup-route-for-websocket-server-in-express
- masteringjs.io/tutorials/express/websockets