Wie verwende ich Websocket mit einer einfachen Express-API?

Kurze Beschreibung der Technologie



Websocket ist ein Kommunikationsprotokoll über eine TCP-Verbindung für Echtzeitnachrichten zwischen einem Browser und einem Webserver.



Der Client und der Server verwenden ein HTTP-ähnliches Protokoll, um eine WebSocket-Verbindung herzustellen. Der Client stellt eine spezielle HTTP-Anforderung, auf die der Server auf bestimmte Weise reagiert.



Hinweise



Trotz der "Ähnlichkeit" der neuen Anforderungen und Antworten mit den HTTP-Anforderungen und -Antworten sind dies nicht der Fall. Beispielsweise hat eine Anforderung einen Textkörper, aber in den Headern befindet sich kein Feld "Inhaltslänge" (was gegen HTTP-Konventionen verstößt). Mehr dazu lesen Sie auf Wikipedia .



Einer der Hauptvorteile der Technologie ist ihre Einfachheit. Auf dem Client und dem Server müssen nur 4 Ereignisse verarbeitet werden:



  1. Verbindung
  2. Error
  3. Botschaft
  4. schließen


Warum Websocket?



Neben ws gibt es zwei weitere Methoden zur kontinuierlichen Datenübertragung: Server-Sent Events (SSE) und Long Polling.



Vergleichen wir die Mechanismen der kontinuierlichen Kommunikation zwischen Server und Client und ziehen wir Schlussfolgerungen darüber, warum es sich lohnt (oder nicht lohnt), einen Websocket zu verwenden.



Websocket sse langes Pooling
Protokoll Websocket (ws oder wss) HTTP (S) HTTP (S)
Geschwindigkeit hoch niedrig niedrig
Richtwirkung von Datenströmen bidirektional unidirektional bidirektional
zusätzlich Bei der Übertragung von Binärdaten werden

einige alte Browser nicht unterstützt
automatische Wiederverbindung, wenn die Verbindung unterbrochen wird


Einer der Hauptvorteile der ws-Technologie ist die Datenübertragungsgeschwindigkeit. SSE und LP verwenden das HTTP (S) -Protokoll und arbeiten ungefähr so:



  1. Antrag auf Änderung stellen;
  2. Wenn Änderungen auf dem Server angezeigt werden, sendet der Server sie.
  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"))


Was ist hier los?



Um einen Server zu erstellen, der ws unterstützt, erstellen wir einen regulären http-Server und binden dann beim Erstellen eines Websockets einen Server daran.



Die Funktion "Ein" hilft bei der Verwaltung von Websocket-Ereignissen. Das bemerkenswerteste Ereignis ist das Nachrichtenereignis. Schauen wir es uns also genauer an.



Hier empfängt die Funktion den Parameter m - die Nachricht, dh was der Benutzer gesendet hat. Auf diese Weise können wir eine Zeichenfolge vom Client senden und auf dem Server verarbeiten. In diesem Fall leitet der Server diese Nachricht einfach an alle weiter, die mit dem Websocket-Server verbunden sind. Das Client-Array des webSocketServer-Objekts enthält alle Verbindungen zum Server. Das ws-Objekt speichert jeweils nur eine Verbindung.



Kommentar



Sie sollten diesen Ansatz nicht in einer realen Anwendung verwenden. Wenn Sie die API auf diese Weise beschreiben, kann der Server eine Anforderung nicht von einer anderen unterscheiden. Wie Sie eine Websocket-basierte API erstellen können, wird später beschrieben.



Die Interaktion mit dem Server auf dem Client sieht folgendermaßen aus:



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);
    }
};


Websocket-basierte API



Im Gegensatz zur REST-API, bei der Anforderungen auf verschiedene URLs verteilt sind, verfügt die Websocket-API nur über eine URL. Um eine vollwertige API basierend auf Websockets zu erstellen, müssen Sie dem System beibringen, eine Anforderung von einer anderen zu unterscheiden. Dies kann wie folgt implementiert werden:



1) Vom Client senden wir Anforderungen in Form einer JSON-Zeichenfolge, die wir auf dem Server analysieren:



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


2) Auf dem Server analysieren wir die Zeichenfolge und wählen das Ereignisfeld aus - den Typ der Anforderung. Schreiben wir die entsprechende Antwort für jeden Typ auf:



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);
   }
}


Auf diese Weise können wir je nach Anforderung unterschiedliche Anforderungen an den Server senden und die Antwort verarbeiten.



Fazit



Wenn Sie die Aufgabe erhalten haben, eine API zu erstellen, und festgestellt haben, dass der Kunde nicht an der Unterstützung alter Browser interessiert ist, ist eine WebSocket-basierte API eine ausgezeichnete Wahl. Für Ihre Bequemlichkeit haben wir den Code für die Client- und Serverteile unter dem Link vorbereitet .



All Articles