A bit of R&D this morning into websockets. Previous games like Naked on Pluto and Germination X have made use of standard HTTP protocol for their client server communication. This is easy to set up (as a newbie web programmer) and fine for prototyping and proof of concept – but has some serious problems with regard to scale.
The first problem is that the direction is one way, clients always have to call the server in order to get data. This has serious impact on how realtime applications work – as they need poll – “has anything changed yet”… “has anything changed yet”…
More seriously, the server has no real notion of who the client is and what they have received already, so all the data needs to be sent for each poll. This results in duplicate data being sent, and is a waste of bandwidth.
Underlying the HTTP protocol are sockets for sending the data – each request is treated as a distinct event so a socket is created and destroyed to return the response. A better way is to hook into this lower level and use sockets directly – each client then has a unique connection on the server, and data can be sent in both directions. Also the server is told when the socket is disconnected so things can be cleaned up.
On the client side, websockets are a standard part of HTML5 so they are fairly simple to use from Javascript:
socket = new WebSocket('ws://localhost:8001/websocket'); socket.onopen= function() { socket.send('hello from client'); }; socket.onmessage= function(s) { alert('server says: '+s.data); };
On the server I’m using Clojure, and after a bit of fiddling around with my own socket server implementation, I found Webbit which takes all the hassle away:
(defn -main [] (println "starting up") (doto (WebServers/createWebServer 8001) (.add "/websocket" (proxy [WebSocketHandler] [] (onOpen [c] (println "opened" c)) (onClose [c] (println "closed" c)) (onMessage [c j] (println "message recieved: " c j) (.send c "hello from server")))) (.add (StaticFileHandler. ".")) (.start)))
This approach takes us from perhaps 100’s of simultaneous connections for an online game into more like 10,000 theoretically – so much more into the big league, but also more importantly persistent connections like this allow for some interesting game mechanics.