25 Aug 2007

Fun with HTTP

Now that Nebula3 is getting a little more complex it's important to know what's going on inside a running application. In Nebula2, there were a couple of in-game debug windows (a texture browser, a "watcher variable" browser, and so on...). But creating new windows was a difficult and boring job (especially because of all the layout code). For Nebula3 I wanted something easier and more powerful: a simple built-in HTTP server which serves HTML pages with all types of debug information. The idea isn't new, others have done this already, but with Nebula2's IO and networking subsystems it wasn't a trivial task to write a HTTP server.

Turns out in Nebula3 it's just a couple of lines (I was actually surprised myself a little bit, even though I wrote the stuff), the TcpServer class already handles all the connection stuff, throw in a couple of stream readers and writers to decode and encode HTTP requests and responses and you have a simple HTTP server written in a couple of hours.

Here's roughly how it works:
  1. create and open a TcpServer object
  2. once per frame (or less frequently) poll the TcpServer for an array of TcpClientConnections (these are all the outstanding requests from web browsers)
  3. for each TcpClientConnection:
    1. attach a HttpRequestReader to the receive stream
    2. attach a HttpResponseWriter to the send stream
    3. decide what to send back based on the request, and fill the response with the result
    4. call TcpClientConnection::Send()
That's it. The actual HTTP protocol coding/decoding happens in the new classes HttpRequestReader and HttpResponseWriter.

Here's the first message served from a Nebula3 application into a web browser:



What's missing now is some sort of HtmlWriter to write out simple HTML pages with the actual content, and a HttpImageWriter to send images to the web browser (to provide a gallery of all currently existing Texture objects).

Fun stuff.