WebSockets im Überblick

Push me to the limit

Matthias Weßendorf
Hallo WebSocket-Welt!

Das WebSocket-Client-API ist überschaubar. Im Wesentlichen werden drei Callbacks (onmessage, onclose und onopen), eine Versandfunktion (send()) sowie die close()-Funktion zum Beenden der Verbindung angeboten. Der Aufbau des Kommunikationskanals erfolgt über den Konstruktor: var helloWS = new WebSocket(„ws://entwickler.com“);. Eine sichere WebSocket-Verbindung wird durch wss:// erreicht. Die drei angesprochenen Callbacks werden genutzt, um auf Ereignisse des Servers zu reagieren. Beim Überschreiben der onmessage-Funktion werden in der Regel die empfangenen Daten extrahiert und im Browser visualisiert:

Listing 2
 

Sämtliche Callback werden mit einem event-Argument aufgerufen. Im Fall einer onmessage()-Implementierung enthält das Event ein data-Feld, das die Payload des Servers beinhaltet. Diese abstrakte Payload kann ein einfacher String, wie „Hello World“, aber auch eine komplexere JSON-Struktur sein.

Um das Gelernte in die Tat umzusetzen, benötigt man nun einen Server, der das WebSocket-Protokoll unterstützt. Glücklicherweise steht auf der Seite von webSockets.org [3] ein einfacher Ping-Server bereit, der für erste Gehversuche mit dem WebSocket API herangezogen werden kann. Das erspart die Installation eines Servers. Ein kleines Skript veranschaulicht das Senden und Empfangen von (WebSocket-)Daten:

Listing 3
 
Click me

Über den Konstruktor wird die Verbindung zum Echo-Service aufgebaut. Der onmessage Callback verarbeitet die empfangenen die Daten. Diese HTML-Seite kann mit einem WebSocket-kompatiblen Browser, wie Firefox 4 oder Chromium 7, lokal geöffnet werden. Sobald das „Click me“-DIV-Element angeklickt wird, sendet unser Programm „Hello World!“ zum Server, der diese Zeichenkette wieder an den Browser zurückschickt (siehe onmessage()). Ein Chat kann mit dem vorgestellten Echo-Service allerdings nicht erstellt werden, da der Dienst lediglich Daten zum sendenden Client zurückschickt und nicht an alle verbundenen Browser.

(Java-)Implementierung für WebSockets

Für die Programmierung von echten WebSocket-Anwendungen kommt man um die Installation eines eigenen Servers nicht umhin. Doch gibt es bereits (Java-EE-)Server, die WebSockets verstehen? Derzeit gibt es verschiedene Java-Server, die WebSocket-Support anbieten. Das jWebSocket-Projekt [4] bietet einen Open-Source-Java-Kommunikationsserver [5]. Daneben gibt es auch kommerzielle Lösungen, z. B. das Kaazing Gateway [6], das zahlreiche Protokolle wie STOMP oder XMPP und sogar die Integration von VNC und WebSocket unterstützt [7].

Nach und nach bauen auch die klassischen Java-EE-Container WebSocket-Unterstützung ein. Aktuell gibt es sie im Jetty-Container (Versionen 7 und 8) oder im Resin-4.x-Container der Firma Caucho. Das kommende Glassfish-3.1-Release bietet ebenfalls WebSocket. Aber auch außerhalb der Java-Welt wird an WebSocket-Support gearbeitet. So kann WebSocket beispielsweise für den Apache-HTTPD-Server [8] oder das mehr und mehr populär werdende Node.js-Framework [9] nachgerüstet werden.

Glassfish 3.1

Die kommende Version des Glassfish-Containers bietet neben Enterprise-Features wie Clustering auch einige neue APIs wie z. B. für WebSocket. Die derzeitige Version des API steckt noch in den Kinderschuhen, sodass Änderungen am Design zu erwarten sind. Die einfachste WebSocket-Anwendung ist ein Echo-Service, wie er oben bereits beschrieben wurde. Die Programmierung geschieht in nur wenigen Zeilen:

Listing 4: Echo WebSocket mit Glassfish
package de.javamagazin.websockets;

import java.io.IOException;
import com.sun.grizzly.websockets.*;

public class EchoWebSocketApp extends WebSocketApplication
{
  public void onMessage(WebSocket socket, DataFrame data) throws IOException
  {
    socket.send(data.getTextPayload());
  }
}

Zentraler Einstiegspunkt ist die abstrakte WebSocketApplication-Klasse, mit der alle Clients, also Implementierungen des WebSocket-Interface, verbunden sind. Innerhalb der onMessage()-Methode wird die zum Server geschickte Payload direkt wieder an das Senden-Fenster zurückgeschickt. Intern nutzt die WebSocketApplication Klasse dabei die BaseServerWebSocket-Implementierung. In echten Anwendungen benötigt man jedoch eine spezialisiertere WebSocket-„Client“-Implementierung, um anwendungsspezifische Logik zu realisieren.

Skizze: Real-Time Twitter Stream

Die Programmierung und Nutzung einer eigenen WebSocket-Klasse soll am Beispiel von Twitter skizziert werden. Twitter besitzt einen Streaming-Service, der in Echtzeit sämtliche Tweets ausgibt. Das Twitter API bietet die Möglichkeit diese nach Trends zu filtern. So könnte eine Webseite ein Eingabefeld anbieten, um Tweets zu einem bestimmten Trend anzuzeigen. Die auf dem Server ankommenden Nachrichten sollen mit dem Glassfish WebSocket API zum Browser geschickt werden:

Listing 5: WebSocket-Anwendung mit eigenem Client
public class TwitterWebSocketApplication extends WebSocketApplication
{
  public WebSocket createSocket(NetworkHandler handler,
      WebSocketListener... listeners) throws IOException
  {
    return new TwitterStreamWebSocket(handler, listeners);
  }

  public void onMessage(WebSocket socket, DataFrame data) throws IOException
  {
    super.onMessage(socket, data);
    // Client schickt "Twitter Trends" als Payload zum Server
    ((TwitterStreamWebSocket) socket).monitorTwitterStream(
                 new String[] {data.getTextPayload()});
  }
Geschrieben von
Matthias Weßendorf
Kommentare

Schreibe einen Kommentar

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