WebSocketServer

Gerade eben habe ich die erste öffentliche Version meines C++ WebSocketServers veröffentlicht. Es gibt eigentlich nicht viel dazu zu sagen, alle Informationen stehen auf der Webseite: WebSocketServer.

Zusammengefasst ist es ein kleiner Server, der das HTML5-WebSocket Protokoll unterstützt. Um Anwendungen für den Server zu schreiben, kann man diese entweder in C++ oder in LUA einbauen!

 

C++ & Lua WebSocketServer

Hi,

ich möchte eigentlich nur ein kurzes Update zu meinem Projekt C++ & Lua WebSocketServer geben: Das ganze läuft schon recht gut, nur leider ist noch ein kleiner Bug in der Implementierung der HYBI10-En/Dekodierung der den Server ab und zu zum Abstürzen bringt. Das ist natürlich schlecht und muss deshalb erst noch behoben werden!

Just a small update on the C++ & Lua WebSocketServer: Due to a bug in my hybi10-implementation the release will be delayed until I fix that problem – stay tuned!

-agrafix

 

HTML5 WebSocket

HTML5 unterstützt jetzt das Aufbauen von „WebSocket“-Verbindungen. Eine WebSocket Verbindung basiert ähnlich wie HTTP auf dem TCP Protokoll, baut aber eine „dauerhafte“ Verbindung auf. Die Vorteile gegenüber HTTP ist, dass eine Aktion des Servers keine vorhergehende Anfrage des Clients mehr erfordert, wodurch der Server neue Informationen fasst in Echtzeit ausliefern kann. Dadurch kann man eine Menge Traffic und viele unnötige HTTP-Requests sparen, die etwa ein AJAX-JavaScript sonst schicken würde um neue Informationen zu erhalten.
Technisch gesehen baut bei einer WebSocket-Verbindung der Browser mit dem Server eine Verbindung auf, die nach einen Handshake dann bestehen bleibt und über die dann Binär- und Textdaten geschickt werden können.

Leider hat das Protokoll im Handshake einige Sicherheitsprobleme (gehabt?) und sich deshalb ständig verändert. Dieser Artikel bezieht sich also auf die Aktuellste Version (17). Diese wird derzeit von der aktuellsten Chrome Version und anderen Webkit Browsern unterstützt, in Firefox und Opera ist WebSocket wegen der Sicherheitsprobleme derzeit deaktiviert.

Um HTML5 WebSocket zu verwenden ist zunächst ein WebSocket-Server nötig. Ich habe hier nach einer PHP-Variante gesucht und habe dann nach einer Weile folgenden gefunden: php-websocket. Diesen sollte man sich laden und dann kann man ihn per

php -q php-websocket/server/server.php

starten. Jetzt ist ein WebSocket-Server auf „localhost:8000“ zu erreichen. Dort sind derzeit zwei Module geladen, einmal das Modul „echo“ und einmal das Modul „chat“. (Ich werde mich hier nicht mit der Entwicklung eines WebSocket-Server weiter befassen) Das „echo“ Modul nimmt einfach Anfragen entgegen und schickt diese dann an alle Verbundenen Sockets weiter.

Nun kümmern wir uns um die HTML5-Seite von WebSocket, dem User-Frontend. Dafür bauen wir uns erstmal eine einfache HTML5 Seite:





HTML5 WebSocket Test





// hier wird dann das WebSocket-Script reinkommen, siehe unten




Log

Chatbox

Say something

Für die einfache Verwendung des WebSockets habe ich mir eine kleine Wrapper-Library (websocketlib.js) programmiert:

/**
 * Small wrapper library for HTML5 WebSocket
 * 
 * @author Alexander Thiemann 
 * @version 1.0
 * 
 * @param string WebSocket host, eg. ws://localhost:8010/echo
 * @param function Function to be called when socket is connected
 * @param function Function to be called when socket recieves data, takes 1 argument message
 * @param function Function to be called for logging purposes, takes 1 argument log-message
 * 
 * @see http://blog.agrafix.net/2011/11/html5-websocket/
 */
var WebSocketLib = {
	init: function(host, onConnect, onRecv, onLog) {
		this.socket = new WebSocket(host);
		
		this.onLog = onLog;
		this.onRecv = onRecv;
		this.onConnect = onConnect;
		
		this.onLog('Initializing Socket. State: ' + this.socket.readyState);
		
		this.socket.onopen = this._onOpen;
		this.socket.onmessage = this._onMessage;
		this.socket.onclose = this._onClose;
	},
	
	send: function(message) {
		WebSocketLib.socket.send(message);
	},
	
	_onClose: function() {
		WebSocketLib.onLog('Socket Closed.');
	},
	
	_onMessage: function(msg) {
		WebSocketLib.onLog('Recieved new Message from Server: ' + msg.data);
		WebSocketLib.onRecv(msg.data);	
	},
	
	_onOpen: function() {
		WebSocketLib.onLog('Socket is Ready. State: ' + WebSocketLib.socket.readyState);
		
		if (WebSocketLib.socket.readyState == 1) {
			WebSocketLib.onConnect();
		}	
	}
}

Ich denke dort ist alles relativ selbsterklärend. Das WebSocket ist wirklich sehr leicht zu verwenden! Um diese Wrapper-Library zu verwenden, bauen wir in obiges HTML-Grundgerüst bei „// hier wird dann das WebSocket-Script reinkommen, siehe unten“ folgendes ein:

$(document).ready(function() {
	WebSocketLib.init('ws://localhost:8010/echo', 
	function() {
		sockReady();
	},
	function (t) {
		$('#chatbox').append($("

").text(t)); }, function (t) { $('#logbox').append($("

").text(t)); }); function sockReady() { $('#chat').submit(function(e) { e.preventDefault(); var input = $('input[name="message"]'); WebSocketLib.send(input.val()); input.val(""); }); } });

Zuerst warten wir, bis unser HTML-Dokument im Browser aufgebaut ist. Dann geben wir in Zeile 2 an, wo unser WebSocket-Server läuft. Die Funktion in Zeile 4 wird aufgerufen, sobald das WebSocket verbunden ist. Die Funktion Zeile 6-8 wird aufgerufen, wenn eine Nachricht zurückgegeben wird. Die Funktion Zeile 9-11 wird bei Log-Ereignissen (Hauptsächlich zum Debuggen) aufgerufen. Mit WebSocketLib.send(„Nachricht“) in Zeile 19 schicken wir eine Nachricht an den Server.

Wenn nun alles vorbereitet ist, der WebSocket-Server gestartet ist (siehe oben), können wir einem Browser, der WebSocket unterstützt (siehe oben), unsere HTML-Seite aufrufen. Die Log-Ausgabe im HTML-Fenster sieht wie folgt aus:

Initializing Socket. State: 0
Socket is Ready. State: 1

Im Consolenfenster des PHP-Server sehen wir:

2011-11-25 11:26:47 [info] [client 127.0.0.1:30601] Connected
2011-11-25 11:26:47 [info] [client 127.0.0.1:30601] Performing handshake
2011-11-25 11:26:47 [info] [client 127.0.0.1:30601] Handshake sent

Die Verbindung ist nun also aufgebaut. Jetzt sollten wir den „echo“-Server testen. Wir tippen etwas in das Textfeld und schicken es ab. Der Log sagt:

Recieved new Message from Server: test

Und unter „Chat“ steht jetzt „test“. Hat soweit also funktioniert! Jetzt können wir ein neues Browserfenster aufmachen, wieder den Verbindungsvorgang abwarten und dann dort eine Nachricht verschicken. Diese erscheint dann in allen verbundenen Client-Fenstern.

Eigentlich ziemlich einfach zu verwenden, und es öffnet viele neue Möglichkeiten vorallem in Kombination mit Canvas für HTML5-Multiplayer-Games… hoffen wir also, dass es bald von allen Browser voll unterstützt wird! 🙂