Websockets

Aus ProgrammingWiki

Wechseln zu: Navigation, Suche

Wissen Können Projekt
  • Websockets als Alternative zur AJAX
  • Echte bidirektionale Kommunikation
  • Praktische Grenzen bei klassischen Webservern
  • Client-seitige Erstellung von Websocket-Verbindungen
  • Verbindungsmanagement (Fehlerkontrolle, Trennung von Verbindungen)
  • Server-seitiges Management von Websocket-Verbindungen
  • Die Sudoku-Web-App wird um einen Chat-Bereich erweitert
  • Beim Login wird zusätzlich eine Websocket Verbindung hergestellt
  • Eine versendete Nachricht wird an alle Clients weitergeleitet

Aus den vorherigen Kapiteln ist bereits hervorgegangen, dass mittels AJAX Anfragen an einen Server gesendet und von diesem gesendete Antworten asynchron angenommen werden können. Die Verbindung zum Server besteht dabei aber immer nur über den Zeitraum der Anfragenbearbeitung. Eine echte Session über diesen Zeitraum hinaus gibt es nicht. Auch gehen Anfragen immer vom Client aus, eine vom Server ausgehende Benachrichtigung des Clients ist damit prinzipiell nicht möglich. Die einzige Möglichkeit um am Client von Statusänderungen am Server zu erfahren, besteht darin, ständig den Status abzufragen (Polling). Mit Long Polling (Server antwortet auf die Polling-Anfrage erst nach einer festgelegten Zeit oder früher bei Statusänderung) kann die Anzahl der Aufrufe verringert aber nicht minimiert werden.

Websockets eröffnen eine Alternative die sowohl das Session-Handling als auch die bidirektionale Benachrichtigung beinhaltet. Am Webserver wird dazu ein Port geöffnet, der auf externe Anfragen wartet. Verbindet sich ein Client mit diesem Port wird eine bidirektionale Verbindung ausgehandelt die solange besteht bis sie entweder vom Client oder vom Server beendet wird. Diese Verbindung kann nun genutzt werden um aktiv Daten in beide Richtungen zu versenden.

Websockets am Client

Zur Erzeugung einer Websocket-Verbindung muss am Client zunächst ein Websocket erzeugt werden. Das erzeugte Objekt kapselt die Verbindung. Mit der Funktion send können Daten an den Websocket-Server gesendet werden. Um auch Nachrichten vom Server empfangen zu können, muss eine Callback-Funktion mittels addEventListener definiert werden. Bei eingehenden Nachrichten wird diese asynchron aufgerufen. Websocket-Verbindungen nutzen das Websocket-Protokoll, welches wie HTTP auf dem TCP-Protokoll aufbaut. Websocket-URLs müssen demzufolge immer mit "ws:" beginnen.

  • Probieren Sie das Beispiel aus! Eventuell funktioniert es durch Sicherheitsbeschränkungen nicht. Finden Sie heraus wie sichere Websocket Verbindungen aufgebaut werden.
  • Fügen Sie dem Beispiel eine Fehlerbehandlung hinzu
  • Geben Sie eine Meldung aus sobald eine Verbindung hergestellt wurde
  • Senden Sie dem Server ein Objekt und behandeln Sie seine Antwort entsprechend

Websockets am Server

Node.js bietet ein sehr komfortable Möglichkeit einen Websocket-Server aufzusetzen. Bei der Initialisierung wird ein Port festgelegt auf dem eingehende Verbindungen angenommen werden können. Die Annahme erfolgt über eine Callback-Funktion die bei Auslösung des request Events asynchron aufgerufen wird. Sie erhält als Parameter ein Objekt welches die eingehende Verbindungsanfrage repräsentiert. Bei Akzeptanz der Verbindung entsteht ein Verbindungsobjekt, der serverseitige Websocket. Dieser kapselt nun diese spezielle Verbindung und bleibt erhalten solange die Verbindung besteht. Mit der Funktion on können nun weitere Callback-Funktionen definiert werden, die bei eingehenden Daten über diese Verbindung asynchron aufgerufen werden. Mit send können Daten, auch unabhängig von Anfragen, zu jedem Zeitpunkt an den Client gesendet werden.

  • Speichern Sie den Beispielcode in einer server.js-Datei und starten Sie den Websocket-Server mit Node.js
    Hinweis: Das Modul websocket muss vorher mit npm install websocket installiert werden
  • Stellen Sie das Websocket-Client-Beispiel nun auf Ihren eigenen Websocket-Server um
  • Erweitern Sie Client und Server um die Möglichkeit der Verbindungstrennung
  • Trennen Sie am Server die Verbindung zum Client nach 30 Sekunden und behandeln Sie das Ereignis am Client entsprechend
  • Verbinden Sie mehrere Clients mit dem Server und machen Sie sich klar wieviele verschiedene conn Objekte es nun gibt
  • Organisieren Sie die verschiedenen Client-Verbindungen am Server und leiten Sie Nachrichten eines Clients an alle verbundenen Clients weiter
  • Informieren Sie alle Clients darüber, wenn sich ein neuer Client mit dem Server verbunden hat

Projekt und weitere Übungen

Bei einem Chat geht es darum Nachrichten an alle Chatbeteiligten zu senden. Diese sollten am Client immer mit dem vorangestellten Namen des Verfassers ausgegeben werden.

Beispiellösung
WE1-P9.zip (1.8 MB)
  1. AJAX-Comet: Broadcasting
    • Setzen Sie das Broadcasting-Beispiel aus der Vorlesung auf. Verwenden Sie mehrere Browser-Instanzen.
    • Wenn sich immer mehr Clients beim Server registrieren, die Clients jedoch keine Daten senden, entstehen serverseitig immer mehr (leere) Briefkästen. Außerdem ist das für den gesamten Ordner erforderliche Schreibrecht ein problematischer Sicherheitsaspekt. Wandeln Sie die Anwendung so ab, dass anstelle der Briefkästen eine einzige XML Datei für den Server angelegt wird. Diese Datei enthält die ehemaligen Briefkasteninhalte zusammen mit je einem Zeitpunkt, wann diese zuletzt geleert wurden. Bei jedem Abruf des Scripts wird diese XML Datei mit simplexml_load_file geladen und ausgelesen, s. Folien weiter unten. (Das geht mit PHP sehr angenehm und man braucht nur das Schreibrecht für genau diese XML-Datei.)
    • Beurteilen Sie die Performance-Eigenschaften. Es ist eine leichte Verschlechterung gegenüber der Briefkasten-Version zu vermuten.
  2. Bringen Sie das WebSocket-Chat-Beispiel aus der Vorlesung (letzter Teil) zum Laufen.
  3. Wikipedia als Informationsquelle
    • Um aus einem Programm Anfragen an die Wikipedia zu stellen, verwenden Sie die Query-API. Folgen Sie dem Beispiel auf dieser Seite und sehen Sie sich auch an, wie einfach es ist AJAX mit jQuery auszudrücken (API-Dokumentation).
    • Die ermittelten Daten sollen im XML/JSON-Format übertragen und mit SimpleXML von PHP verarbeitet werden.
Persönliche Werkzeuge