A couple of weeks ago we were told that we were to be making a tool for data visualisation. One possibility for visualisation that was brought up was Google Earth. So I decided to try to figure out KML. I started off by looking through examples and the KML reference to get a grip on how it was structured. The format was simple enough that it didn’t take long to get things drawing in Google Earth. It wasn’t long before I stumbled upon the NetworkLink tag, which allowed periodic updates of the ‘document’.
From that point on I researched into HTTP and worked on writing a simple webserver to serve KML to Google Earth. The first thing I tried was just getting something working that I could navigate to in a browser. The first iteration involved just starting up a tcp socket, listening on a port (I used 1337 so I didn’t have to run my server with admin privileges), and for each incoming connection send a HTTP 1.1 header with status ‘OK’ (Code 200), a content-type of ‘text/plain’ and with content-length set to 0. This meant that the browser could connect to the server but would receive nothing.
Next step was to send something. What I did was write out a simple block of html with just a h1 tag in it, then finish writing the header with content-length set to the size of the buffer. Then I’d concatenate the header and body buffers and send the result. Obviously writing directly to the socket would have been better but performance wasn’t a big concern for me at that point. That seemed to work, so the next step was KML.
I replaced my HTML block with a simple block of KML which was meant to draw a rotating rectangle around my house, and wrote a KML file that was supposed to connect to my server and update every 100ms or so. I started the server and opened the KML file in Google Earth. The rectangle spawned, and rotated once or twice then just stopped. My server also stopped getting requests.
This is obviously not what was supposed to be happening, so I looked at my code again to try to figure out what the problem was. After some good hard pondering I came to the conclusion that Google Chrome wasn’t creating new connections to the server every time it updated like I’d assumed. Instead it created one TCP socket and reused it each update. This wouldn’t have been a problem if I’d remembered to close the sockets after I’d used them. What was happening was, Google Earth was requesting data, I received the request and sent it the data through the new socket, then instead of closing the socket I waited on an accept. This meant that all of Google Earths subsequent requests were met with silence as my server no longer was expecting requests on that socket.
So I closed the socket and tried again. It worked. Floating above my house was a rectangle rotating at 10fps. At that point I decided that I’d made enough progress for the night (4am) and left it there.