JavaScript/WebSocket/WebSockets mit node.js

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Server-Implementierung mit node.js

Websocket.svg

Die Implementierung eines WebSocket-Servers setzt voraus, dass Sie auf Ihrem Server eigene Dienste ausführen können. Ein einfacher Shared WebServer mit Apache, PHP und MySQL erfüllt diese Voraussetzung nicht. Ein selbst gehosteter Server, auf dem man einen WebSocket-Dienst starten kann, ist aufwändiger im Betrieb und auch teurer. Für erste Versuche können Sie aber einfach node.js auf Ihrem Computer installieren und damit einen WebSocket-Server starten. Für einen öffentlichen Betrieb können Sie einen eigenen Server betreiben oder Sie halten nach einem Cloud-Anbieter wie Google App Engine, Amazon Web Service oder Microsoft Azure Ausschau. Der Einarbeitungsaufwand ist nicht gering.

Wenn Sie Node.js zur Verfügung haben, schlagen wir für einen einfachen Start die npm Bibliothek ws vor. Für die folgenden Aktivitäten benötigen Sie Erfahrung im Umgang mit der Kommandozeile. Die angegebenen Beschreibungen wurden unter Windows mit node.js Version 16 und NPM 8.3.1 erprobt - eine Überprüfung für Linux oder Mac-Systeme ist noch erforderlich.

Ein Zeitanzeigeservice

Erstellen Sie zunächst einen neuen Ordner für Ihr Websocket-Server Projekt. Darin rufen Sie NPM auf, um die ws Library zu installieren (die Option --save ist nur für ältere NPM Versionen erforderlich und trägt ws in Ihrer package.json Datei als Dependendy ein. Neuere NPM machen das automatisch):

   npm install --save ws

In der package.json fügen Sie nun nun noch eine Zeile "type": "module" hinzu, damit unser Programm als ES6-Modul läuft. Vergessen Sie das Komma nicht! Das Ergebnis sollte so aussehen, oder es zumindest enthalten:

   {
      "type": "module",
      "dependencies": {
        "ws": "^8.12.1"
      }
   }

Erstellen Sie nun eine Datei timeservice.js, die so aussieht:

WebSocket Server unter node.js mit ws Library
import { WebSocketServer } from 'ws';

const socketServer = new WebSocketServer({ port:8443 });

setInterval(() => {
   const data = JSON.stringify({'type': 'time', 'time': new Date().toTimeString()});
   socketServer.clients.forEach((client) => {
      client.send(data);
   });
}, 1000);

Das war's schon? Ja, das war's schon. Wir haben auf eigentlich nötige Features wie Subprotokolle, HTTPS und Authentifizierung verzichtet, und die eigentliche Arbeit macht die ws Library. Und dann ist nicht mehr viel Code erforderlich. Dieser Dienst schickt allen seinen verbundenen Clients im Sekundentakt die aktuelle Zeit. Wir brauchen jetzt noch eine primitive HTML Seite, die als Client für den Socketserver dient. Die könnte so aussehen:

Ein Client für den Zeitservice
<!doctype html>
<html>
<body>
<script>
const timeService = new WebSocket("ws://localhost:8443");

timeService.onmessage = function(e) {
   const data = JSON.parse(e.data);
   if (data && data.type=='time')
      document.body.textContent = data.time;
};
</script>
</body>
</html>

Starten Sie nun node.exe mit der timeservice.js Datei als Parameter und rufen Sie danach in Ihrem Browser die HTML Datei auf. Das können Sie über einen lokalen Webserver machen, oder auch einfach aus dem Dateisystem.

Sie sollten nun eine Zeitanzeige sehen, die sich im Sekundentakt aktualisiert. Öffnen Sie weitere Browser-Tabs und laden Sie das HTML dort ebenfalls. Wenn Sie mögen, bohren Sie ein Löchlein für eingehenden TCP Traffic auf Port 8443 in Ihre Computer-Firewall (aber nur, wenn zwischen Ihnen und dem Internet noch ein Router steht, der Zugriffe von außen verhindert!), laden Sie das HTML auf andere Computer (dann aber nicht mit localhost in der ws-URL, sondern mit der lokalen IP Ihres Computers) und versuchen Sie, den Zeitdienst auch von dort zu erreichen. Viel Glück!

In dem timeservice.js Dienst, den wir unter Node laufen lassen, wird mit setInterval ein Timer erzeugt, der im Sekundentakt aufgerufen wird. Er durchläuft alle aktuell mit dem socketServer-Objekt verbundenen Clients und schickt ihnen ein JSON-codiertes Objekt, das die aktuelle Serverzeit enthält. Jeder send-Aufruf löst im Browser-Tab ein message-Event auf dem WebSocket-Objekt aus. In e.data findet sich die Servernachricht, die nun mit JSON.parse in ein Objekt zurückgewandelt wird. Ist es eine Nachricht vom Typ "time", wird der Inhalt der time-Eigenschaft in den body der Seite geschrieben.

Datensicherheit - WebSockets über HTTPS

ToDo (weitere ToDos)

Artikel muss weitergeführt werden.--Matthias Scharwies (Diskussion) 11:34, 6. Aug. 2016 (CEST)