Recently, I was advised that WebFaction had added support for WebSocket in their custom applications by enabling the according nginx module in their frontend. Obviously, I had to try it out with my own websocket library: ws4py.
Setting up your WebFaction application
Well, as usual with WebFaction, setting up the application is dead simple. Only a few clicks from their control panel.
Create a Custom application and select websocket. This will provide you with a port that your backend will be bound to. And voilà.
Now, your application is created but you won’t yet be able to connect a websocket client. Indeed, you must associate a domain or subdomain with that application.
- http://yourhost/ : for the webapp
- http://yourhost/ws : as the base url for all websocket endpoints
This is just a suggestion of course but this will make it easier for your deployment to follow a simple strategy like this one.
In the WebFaction control panel, create a website which associates your web application with the domain (your webapp can be anything you need to). Associate then your custom websocket application with the same domain but a different path segment. Again, by sharing the same domain, you’ll avoid troubles regarding working around the same-origin security model. I would probably advise as well that you enable SSL but it’s up to you to make that decision.
Once done, you will have now a configured endpoint for your websocket application.
The Custome websocket application will forward all requests to you so that you can run your web and websocket apps from that single port. This is what the demo below allows itself doing. I would recommend that you run two different application processes, one for your webapp and another one for your websocket endpoint. Be antifragile.
Drawing stuff collaboratively
I setup a small demo (sorry self-signed certificate) to demonstrate how you can use HTML5 canvas and websocket features to perform collaborative tasks across various connected clients.
That demo runs a small webapp that also enables a websocket endpoint. When you are on the drawing board, everything you draw is sent to other connected clients so that their view reflects what’s happening on yours. Obviously this goes in any way frm any client to any other clients.
The demo is implemented using ws4py hosted within a CherryPy application. Drawing events are serialized into a json structure and sent over to the server which dispatches them to all participants of that board, and only that board (note, this demo doesn’t validate the content before dispatching back so please conservative with whom you share your board with).
Open the link found in the demo page and share it on as many browsers as you can (including your mobile device). Starting drawing from one device will make all other devices been drawn onto simultaneously and synchronously. Note that the board stays available for up to 5mn only and will disconnect all participants then.
The source code for the demo is located here.
Let me share a bit of feedback about the whole process.
- WebSockets are finally a reality. Unless you’re running an old browser or old mobile platform, RFC6455 is available to you. This means, you can really leverage the power of push from the server. Mind you, you might want to look at Server-Side Event as well.
- There isn’t yet a clear understanding on how to properly configure your server resources. In my demo, the whole webapp also hosts the websocket app but this is probably not a good idea if you have a large amount of connected clients or intensive work done server side. Even though the initial connection is initiated from a HTTP request, I would suggest the websocket server is disconnected from the HTTP server process.
- Security wise, I would suggest you follow the usual principles of validating that any data coming through before you process or dispatch them back.
- WebFaction supports for websocket is dead easy to setup and fast (at least, since my demo is hosted in Europe and I live in France, I almost cannot see any delay). I would consider their performances good enough to support some really funky real-time applications.
- jCanvas is really useful to unify your canvas operations. For this demo, it’s been a blessing.
- Device motion events are low level and you need to do a lot of leg work to actually make sense of them. This demo is probably not making a really good use of them.
- There seems to be no universal way to detect that you are running on a mobile device. Go figure.
Next, I wouldn’t mind adding websocket to that fun demo from the mozilla developer network.