Push me to the limit

WebSockets im Überblick

Matthias Weßendorf

Real-Time-Data ist derzeit ein großes Thema. Übernahmen innerhalb der „Cloud-Computing-Szene“, z. B. von Salesforce.com, untermauern diesen Trend [1]. In der heutigen Welt ist es immer wichtiger, nahezu in Echtzeit seine Daten und deren Veränderung abfragen und analysieren zu können. Für die Umsetzung einer Echtzeitlösung bietet sich mehr und mehr WebSockets als Alternative zu den üblichen Comet „Hacks“ an.

Als Beispiele für mögliche Einsatzfelder von Echtzeitlösungen wird oft Collaborative Tooling genannt: Verschiedene Nutzer schreiben zeitgleich an einem Dokument und werden bei signifikanten Änderungen direkt benachrichtig. Zusätzlich können sie per Chatfunktion bestimmte Änderungen diskutieren. Die Firma Atlassian hat bereits damit begonnen, ähnliche Funktionalität in ihr JIRA Studio einzubauen [2]. JIRA-Nutzer werden nun informiert, was gerade innerhalb des JIRA Studio geschieht oder ob beispielsweise neue E-Mails angekommen sind. Daneben gibt es weitere klassische Anwendungsfälle, z. B. Liveübertragungen der Fußballbundesliga. Aber auch die Monitoring-Software eines Application-Servers profitiert von der einer echtzeitnahen Analyse der Daten. Es lassen sich viele weitere Anwendungsfälle finden: Denkt man ein wenig über die eigene Anwendung nach, so findet man in fast jedem System Punkte, an denen diese Funktionalität sinnvoll ist. Doch wie geht man das an?

Real-Time Revolution

Lädt ein Benutzer eine Webseite, die aktuelle Daten enthält, so besteht die Gefahr, dass diese Daten sehr schnell veraltet sind. Bis zur Etablierung von Server-Side-push-Techniken wie Comet/Bayeux wurden solche Seiten mit (Ajax) Polling aktualisiert. Das hat den Nachteil, dass der Server alle n Sekunden gefragt wird, ob er neue Daten für den Browser hat. Je länger das Abfrageintervall ist, desto höher ist die Latenz. Will man das vermeiden, stellt man zwangsläufig den Client so ein, dass der Server sehr häufig angefragt wird. Das führt wiederum zu unnötigem Traffic zwischen Browser und Server. Zusätzlich kommt hinzu, dass dadurch auch serverseitige Ressourcen bei der Abhandlung der zahlreichen Requests verschwendet werden.

Mit Comet/Bayeux wird oft Long Polling oder HTTP-Streaming gesetzt (Abb. 1). Bei Long Polling wird ein Request zum Server geschickt, allerdings hält der Server den Request für einen bestimmten Zeitraum offen und beendet ihn erst, sobald neue Daten verfügbar sind. Konnten keine neuen Daten ermittelt werden, so wird der Request ebenfalls nach einem konfigurierbaren Timeout-Intervall geschlossen. Im Browser wird nun die Response verarbeitet, um direkt einen neuen Request zu senden, der auf weitere Daten wartet.

Kommt HTTP-Streaming zum Einsatz, so schickt der Client einen einzigen Request, der niemals vom Server beendet wird. Sobald Daten auf dem Server verfügbar sind, werden diese scheibchenweise in die Response geschrieben. Abbildung 1 stellt Long Polling und HTTP-Streaming einander gegenüber.

Abb. 1: Long Polling und Http-Streaming

Der Long-Polling-Ansatz hat jedoch zwei erhebliche Probleme: Es werden mehrere vollständige Requests an den Server geschickt, inklusive HTTP Header. Das verursacht unnötige Daten, die über die Leitungen gehen. Zusätzlich besteht auch hier das Latenzproblem. Erreichen den Webserver neue Daten, während die Response zum Client geschickt wird, besteht sogar die Gefahr, dass sie verloren gehen. Diese Nachteile können jedoch mit HTTP-Streaming umgangen werden. Doch hier warten andere Probleme: Firewalls und Proxy-Server können die Latenzzeit erheblich erhöhen oder gar den Response buffern. Die Lösung ist hier der Einsatz von Long Polling.

Hinzu kommt, dass ein Browser mit Comet/Bayeux lediglich Daten empfangen kann. Will er dem Server Daten senden, muss er einen zusätzlichen (Ajax) Request an den Server senden.

WebSocket – Bidirektionaler Kommunikationsstandard für das Web

WebSocket, ein bidirektionaler, Full-duplex-Kommunikationskanal, tritt an, um die oben genannten Probleme zu lösen. Der Verbindungsaufbau zwischen Client und Server erfolgt über den WebSocket Protokol Handshake (Abb.2):

Listing 1

GET /text HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: www.websocket.org
...

HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
...

Abb. 2: WebSocket Handshake

Sobald die Verbindung zwischen einem Browser und dem WebSocket-Server hergestellt ist, können Daten zwischen beiden Parteien ausgetauscht werden. Mit WebSocket kann ein Client auch mit anderen Servern kommunizieren, anders als bei traditionellem Ajax, wo nur mit dem Server kommuniziert werden kann, der die Anwendung ausliefert. Proxy-Server stellen mit WebSocket kein Problem mehr da, weil im Fall einer solchen Installation automatisch ein Tunnel erstellt wird: Nutzt der Browser einen Proxy-Server, wird das clientseitig festgesellt und der Proxy-Server wird mittels der HTTP-CONNECT-Methode angewiesen, über TCP/IP eine Verbindung zu einem bestimmten Host zu öffnen. Interessant ist die Tatsache, dass WebSocket von zwei Organisationen standardisiert wird: WebSocket Client API (W3C) und WebSocket Protokol (IETF). Damit hebt sich der WebSocket-Ansatz deutlich von proprietären Comet- und Bayeux-Ansätzen ab: Bayeux beschreibt mögliche APIs, definiert aber nicht Funktionsnamen oder deren Signatur.

Geschrieben von
Matthias Weßendorf
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.