August 22, 2010

In my previous post, I mentioned the goal of separating protocols from the client object. As an experiment, I started writing a HTTP service using the new code. This would let me run a light web server as a service in conjunction with something like WebSockets on the same, single-threaded server.

You definitely don't want to waste time serving big files in a single threaded application because it blocks but for little things like a login page it could be handy. Plus, I've written web based apps for years but never fully understood what was happening under the hood and here was a chance to find out.

The actual HTTP protocol is pretty simple. It only has eleven commands (or methods); HEAD, GET, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, and PATCH. Currently, I only support one, GET (which is easily 99.9% of the web). All other methods are responded to with a status code 501 Not Implemented.

Here's my index.html rendered on Chromium:

This actually represents three separate HTTP GET requests; the index.html file, the skull image, and the tiny skull favicon shown on the tab.

The skull is a compressed SVG, to get Chromium to display it I had to add Content-encoding parameter to my HTTP Response;

No longer line-based; the new API has get_ch() to get one character or get_input() to retrieve the entire input buffer. This is support users that want to write features like text editors and command completion.

New event; on_input() that is called when the data is received from the client.

When run under Linux, it uses the Epoll API introduced in Linux kernel 2.5.44. All other platforms user Select().

I kept the server polled from within the user's game loop. I know that event and callback driven designs are more efficient, but I really like the approachability of that pattern. It can be hard to think in terms of callbacks.