Tales of the minotaur or long polling with node.js
Long polling principle
“The browser makes an Ajax-style request to the server, which is kept open until the server has new data to send to the browser, which is sent to the browser in a complete response. The browser initiates a new long polling request in order to obtain subsequent events.”
There are however few issues, or architectural decisions, which needs to be solved in order to start building a long poll server. Solutions and patterns used to solve these issues can affect crucial elements such as performance, security or stability of the server.
Communication transport between server and client
There are numerous ways which can be used to asynchronously communicate between server and client including WebSockets, Flash Sockets, XMLHttpRequests or AJAX multipart streaming. However some browsers doesn’t support Cross-Origin Resource Sharing to solve same origin policy, therefore, the only cross-browser compatible way is to use JSONP polling as transport method.
Server side session management
Identification of polling clients
When the client sends the first request to the server, it needs to be further uniquely identified by some sort of session ID which will serve as a key identifier for the next polling requests, otherwise the server wouldn’t be able to maintain connection with a client. Again after some consultation with folks at StackOverflow I decided to use signed secure cookies generated by cookie-node node.js module. When new poll request is sent to the server, client is identified based on the session ID stored in a secure cookie which is decrypted on the server side.
Secure cookie is assigned to the browser context, but user can open multiple tabs with the same long polling web application within one browser. This can lead to serious problems during long polling therefore assigned session should be reused for each new tab which requires separate polling connection. Minotaur server solves this issue by creating a new client connection for each new long polling tab. This client connection have it’s own unique ID used for identification and is created withing existing session which keeps track of concurrently polling clients. Number of these parallel connections within one browser is restricted by the specific browser.
With WebSockets approaching I will probably extend minotaur server communication transports with this great technology and leave JSONP polling as fallback option for situations where WebSockets can’t be used. You can find source codes of the minotaur together with two chat example web applications which are using this long poll server at github.