libwebsockets - HTML5 Websocket server library in C

November 1, 2010

Browser vs Apps

It's been clear since browsers first started becoming popular in the 90s that they were going to be the answer to standardized cross-platform support, but somehow there were never quite enough pieces of the puzzle to replace applications outright. Java or Flash or me-toos like Sliverlight were needed and despite Flash solving the problem of video delivery, there hasn't really been a shift away from old-style apps to the browser. (When I wrote Penumbra in 2007, I was able to use an exclusively https browser interface, but that's only because it was fundamentally a filesharing app that didn't challenge simple HTML). The issue has never been more urgent because the number of incompatible platforms in wide use has been increasing, with iPhone. Android, Macs and Linux boxes alongside Windows. Making native apps for each platform is still possible, but it's now a very large effort to cover and support all the platforms well natively.

HTML5 vs flash

HTML5 looks like it might have enough firepower to eliminate flash, it has already proven with web-m that it will be able to replace flash for the most critical job it does for the internet as a whole, video delivery, without having to worry too much about patents. Because of that, it has increasing mindshare and there's already a lot of support in place in recent browsers, eg, Chrome and Firefox 4.0b6 at the time of writing, and considering Chrome is webkit, that covers many embedded scenarios too; Apple have committed themselves to HTML5 support in order to screw over Adobe... uh... I mean as part of their love of open standards. Adobe did make actionscript a standard, but they have never been able to get away from being denounced as the main cause of browser crashes. HTML5 moves all the hard work Adobe tried to do by themselves in terms of cross-platform media support to the people writing the browser and eliminates the need for Flash.

Websockets

Websockets are a new part of HTML5 that allow the client to get away from the ancient bias of browsers that any network connection is ultimately there to serve some kind of ...ML, HTML or XML or whatever. Websockets start off life as an HTTP connection, but the client immediately sends a request to the HTTP server to "upgrade" the protocol to websocket protocol. After a complex handshake confirming both sides really speak websocket, websocket protocol is MUCH simpler than HTTP. In the case of UTF-8 text packets, it's as simple as sending 0x00 <vari-size payload> 0xff to terminate. Binary payload packets have a slightly more complex length descriptor and then the payload with no terminator. The value of it over http is the javascript on the client side can just get the raw binary or UTF-8 payload, and the socket stays open for async traffic in either direction. There is no HTTP header overhead on each packet, as mentioned for UTF-8 the protocol overhead is 2 bytes per packet only. There's no huge XML encode / decode overhead either, so this is a great transport for low-latency data like speech, and it's no-messing async nature lets it carry event information too ajax-style. Because (once the connection is established) the protocol overhead is so low, it's very suitable for weak embedded devices that have some kind of network connectivity but no real UI capability or CPU cycles for bloating data into formats browsers otherwise prefer.

Websocket servers

Sounds good right? Well, to use it practically you need server-side support, because you are literally using a new socket-level protocol other than http. There are Java and Python implementations suitable for Apache... but... unlike http there are no C library implementations suitable for embedded devices. So, I wrote libwebsockets to allow embedded devices to participate in the new UIs possible with HTML5 and websockets.

Introducing libwebsockets

libwebsockets (in git at http://git.warmcat.com/cgi-bin/cgit/libwebsockets/ ) is a lightweight GPL2 http and websocket server that hides all the protocol handshakes and detail from the user code driving the server. Because it supports file serving on http, it is able to provide a single listening socket that can serve your html script page normally and then when the browser starts running your script, come back and make websocket connections to the same port. A test server is provided http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/test-server/test-server.c because everything to do with the protocols is handled by the library, it's very simply able to serve http and websockets using a single callback.