Comment utiliser Websocket avec une API Express simple?

Brève description de la technologie



Websocket est un protocole de communication via une connexion TCP, conçu pour échanger des messages entre un navigateur et un serveur Web en temps réel.



Pour établir une connexion WebSocket, le client et le serveur utilisent un protocole similaire à HTTP. Le client effectue une requête HTTP spéciale à laquelle le serveur répond d'une manière spécifique.



Notes



Bien que les nouvelles requêtes et réponses soient "similaires" aux requêtes et réponses HTTP, elles ne le sont pas. Par exemple, la demande a un corps, mais les en-têtes n'ont pas le champ Content-Length (qui enfreint les conventions HTTP). Vous pouvez en savoir plus à ce sujet sur Wikipedia .



L'un des principaux avantages de la technologie est sa simplicité. Il n'y a que 4 événements sur le client et le serveur à traiter:



  1. lien
  2. Erreur
  3. message
  4. Fermer


Pourquoi Websocket?



En plus de ws, il existe deux autres méthodes de transmission de données continue: les événements envoyés par le serveur (SSE) et l'interrogation longue.



Comparons les mécanismes de communication continue entre le serveur et le client, et tirons également des conclusions sur les raisons pour lesquelles il vaut (ou ne vaut pas la peine) d'utiliser un websocket.



Websocket sse longue mise en commun
protocole websocket (ws ou wss) HTTP (S) HTTP (S)
la vitesse haute faible faible
directionnalité des flux de données bidirectionnel unidirectionnel bidirectionnel
aditionellement transfert de données binaires, il n'y a

pas de support pour certains anciens navigateurs
reconnexion automatique lorsque la connexion est interrompue


L'un des principaux avantages de la technologie ws est la vitesse de transfert des données. SSE et LP utilisent le protocole HTTP (S) et fonctionnent comme ceci:



  1. Faire une demande de modifications;
  2. Si des modifications apparaissent sur le serveur, le serveur les envoie;
  3. , .


:



  1. .
  2. , HTTP(S).
  3. , .


api.



const http = require("http");
const express = require( "express");
const WebSocket = require( "ws");

const app = express();

const server = http.createServer(app);

const webSocketServer = new WebSocket.Server({ server });

webSocketServer.on('connection', ws => {
   ws.on('message', m => {
webSocketServer.clients.forEach(client => client.send(m));
   });

   ws.on("error", e => ws.send(e));

   ws.send('Hi there, I am a WebSocket server');
});

server.listen(8999, () => console.log("Server started"))


Que se passe t-il ici?



Pour créer un serveur prenant en charge ws, nous créons un serveur http normal, puis nous y lions le serveur lors de la création d'un websocket.



La fonction «on» permet de gérer les événements Websocket. L'événement le plus notable est l'événement de message, alors examinons-le de plus près.



Ici, la fonction reçoit le paramètre m - le message, c'est-à-dire ce que l'utilisateur a envoyé. Ainsi, nous pouvons envoyer une chaîne depuis le client et la traiter sur le serveur. Dans ce cas, le serveur transmet simplement ce message à toutes les personnes connectées au serveur websocket. Le tableau clients de l'objet webSocketServer contient toutes les connexions au serveur. L'objet ws ne stocke qu'une seule connexion à la fois.



Commentaire



Vous ne devriez pas utiliser cette approche dans une vraie application. Si vous décrivez l'API de cette manière, le serveur ne peut pas distinguer une requête d'une autre. Comment vous pouvez créer une API basée sur un websocket sera écrit plus tard.



L'interaction avec le serveur sur le client ressemblera à ceci:



export const wsConnection = new WebSocket("ws://localhost:8999");
wsConnection.onopen = function() {
    alert(" .");
};

wsConnection.onclose = function(event) {
    if (event.wasClean) {
        alert('  ');
    } else {
        alert(' '); // , ""  
    }
    alert(': ' + event.code + ' : ' + event.reason);
};

wsConnection.onerror = function(error) {
    alert(" " + error.message);
};

export const wsSend = function(data) {
// readyState - true,   
    if(!wsConnection.readyState){
        setTimeout(function (){
            wsSend(data);
        },100);
    } else {
        wsConnection.send(data);
    }
};


API basée sur Websocket



Contrairement à l'API REST, où les requêtes sont réparties sur différentes URL, l'API Websocket n'a qu'une seule URL. Afin de créer une API à part entière basée sur des websockets, vous devez apprendre au système à distinguer une requête d'une autre. Cela peut être implémenté comme suit:



1) Depuis le client, nous transmettrons les requêtes sous la forme d'une chaîne json, que nous analyserons sur le serveur:



const sendMessage = (message) => conn.send(JSON.stringify({ event: "chat-message", payload: { userName, message }}));


2) Sur le serveur, nous analysons la chaîne et sélectionnons le champ d'événement - le type de requête. Écrivons la réponse correspondante pour chaque type:



const dispatchEvent = (message, ws) => {
   const json = JSON.parse(message);
   switch (json.event) {
       case "chat-message": webSocketServer.clients.forEach(client => client.send(message));
       default: ws.send((new Error("Wrong query")).message);
   }
}


Ainsi, nous pouvons envoyer différentes requêtes au serveur et traiter la réponse en fonction de la requête.



Conclusion



Si vous avez été chargé de créer une API et que vous découvrez que le client n'est pas intéressé par la prise en charge d'anciens navigateurs, une API basée sur WebSocket est un excellent choix. Pour votre commodité, nous avons préparé le code pour les parties client et serveur sur le lien .



All Articles