Letzten Freitag hatten wir eine Techrallye bei Xebia. Wir konnten unser Thema wählen: MongoDB oder Websockets oder Canvas. Ich habe mich mit Albert zusammengetan. Es gab auch ein anderes Websockets-Team, bestehend aus Mischa, Ron und Frank.
Einführung
Ich möchte die Einführung überspringen, weil schon viel über Websockets geschrieben wurde und Sie wahrscheinlich so schnell wie möglich loslegen möchten. Im Abschnitt Quellen finden Sie weitere Informationen. Für den Moment müssen Sie nur wissen, dass es schnell ist, fast keinen Overhead hat, eine permanente Verbindung offen hält (so dass der Server Daten an den Client schicken kann, kein Polling erforderlich!
Installation
Wenn Sie Maven 2+ verwenden, müssen Sie nichts herunterladen. Starten Sie einfach ein Maven War-Projekt und fügen Sie das jetty-maven-plugin hinzu (wir haben Version 7.2.1.v20101111 verwendet), fügen Sie eine Abhängigkeit zu jetty-websocket hinzu (innerhalb des Projektelements) und schon können Sie loslegen.
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-websocket</artifactId>
<version>7.2.1.v20101111</version>
</dependency>
Zerlegen des WebSocketChatServlet-Beispiels
Eine Beispielanwendung ist im Lieferumfang von Jetty enthalten. In
Ihr eigenes Servlet erstellen
Da ich in der Vergangenheit Struts und Spring MVC verwendet habe und die Servlet-Konfiguration immer kopiert habe, ist es schon eine Weile her, dass ich mein eigenes Servlet in die web.xml eingefügt habe. Hier ist ein kleiner Ausschnitt, der Ihnen helfen soll (dies war wahrscheinlich einer der schwierigsten Teile ;) ):
<servlet>
<servlet-name>hw</servlet-name>
<servlet-class>com.xebia.ws.HelloWorldServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hw</servlet-name>
<url-pattern>hw.do</url-pattern>
</servlet-mapping>
Das HelloWorldServlet erweitert WebSocketServlet und Sie müssen die Methode doWebSocketConnect implementieren. Diese Methode gibt einen WebSocket zurück. Für den Moment genügt es, einen neuen HelloWorldWebSocket zu erstellen.
HelloWorldWebSocket implementiert WebSocket. Die onConnect-Methode empfängt ein Outbound-Objekt. Mit diesem Objekt ist es möglich, Daten an den Client zurückzusenden. Das Outbound-Objekt ist ein Feld des WebSocket-Objekts, so dass wir es in der onMessage-Methode verwenden können.
Die onMessage-Methode:
public void onMessage(byte opcode, String data) {
outbound.sendMessage("pong");
}
Wenn wir Daten in Javascript (mit send()) senden, antwortet der Server mit "pong".
Die Javascript-Seite
Auch das Javascript ist sehr einfach. Ich habe das jQuery-Plugin hinzugefügt, um Daten zu einem div mit der id bla hinzuzufügen, aber Sie können es auch auf die altmodische Weise tun.
var ws=new WebSocket("ws://10.0.0.230:8080/hw.do");
ws.onmessage = onMessage;
ws.onopen = onOpen;
function onMessage(m) {
$("#bla").append(m.data + "
");
}
function onOpen() {
console.log("Verbindung geöffnet")
}
Funktion senden(){
console.log("sendet ping");
ws.send("ping");
}
Zum Testen verwenden wir Safari, das über eine sehr schöne Konsole verfügt (verfügbar unter dem Menüpunkt Entwickeln, Fehlerkonsole anzeigen). Indem wir send() in die Konsole eingeben, senden wir einen Ping, der mit einem Pong beantwortet wird. Die Antwort wird im Div mit der id bla protokolliert. Es ist sogar möglich, einen einfachen Websocket-Client zu schreiben, der nichts weiter als die Konsole benötigt:
var m=new WebSocket("ws://10.0.0.230:8080")
m.onmessage=function(m){ console.log(m.data); };
Dieses Codestück gibt die Nutzdaten jeder empfangenen Nachricht aus. Das Senden erfolgt mit m.send("zu sendende Daten");
Probleme
Ich denke, http ist das Protokoll für Websockets
Wir haben den Browser verwendet, um zu testen, ob das WebSocketServlet funktioniert. Natürlich verwenden Websockets das Präfix ws:// oder ws:// und wir haben https:// verwendet. Ich habe diesen Fehler ein paar Mal gemacht.
WebSocket ist nicht bereit
Wir haben versucht, Daten über den Socket zu senden, erhielten aber eine INVALID_STATE_ERR. Anscheinend ist der WebSocket nicht sofort nach der Erstellung bereit. Nachdem der WebSocket bereit ist, wird die Funktion onopen aufgerufen und dann ist er bereit zum Senden und Empfangen. Das Feld readyState bei einem WebSocket ist ein nützliches Feld, um den Status des Sockets zu überprüfen (0=verbunden, 1=offen, 2=geschlossen, 3=geschlossen). Versuchen Sie also nicht, etwas mit dem Websocket zu tun, bevor onopen aufgerufen wird.
WebSocket in Firefox 4 deaktiviert
Während wir mit dem Programmieren beschäftigt waren, stattete uns Dan North einen Besuch ab. In einer sehr coolen Präsentation im Stil einer Improvisation wies er uns auf einen Artikel über einige Sicherheitsprobleme mit Websockets hin.
Fazit
Websockets ist eine sehr coole Technologie und ich bin sehr froh, dass sie ein Thema der Techrallye war. Sie können gerne Fragen stellen. Mindestens 5 Leute bei Xebia sind jetzt Websockets-Experten und noch mehr haben sich zwei Präsentationen dazu angehört.
Quellen
Jetty WebSocket Server im Webtide Blog
WebSockets-Spezifikation beim W3C
Einführung in WebSockets auf SlideShare
Maven Jetty Plugin auf Codehaus
WebSockets in Firefox 4 auf Mozilla Hacks deaktiviert
HTML5-Serie: Teil 6: WebSockets auf Xoriant Blog
Verfasst von
Jeroen van Wilgenburg
Unsere Ideen
Weitere Blogs
Contact



