05 Jul, 2011
Realtime connections between web servers and web browsers
Posted by: Peter In: Web
In the early days of the web, web pages were very static in content, once the page was loaded nothing on the page would change until you reloaded it. Then came Ajax and allowed us to do partial reloads of the page. During the last few years the web has evolved even more. Today you see a lot of web applications, such as Facebook and Google+, where content is updated as you are watching the page. This has been made possible by using different techniques to keep a connection to the web server open and be able to push content from the web server to the connected clients. The main technique to allow this in web browsers today is what is called Comet.
Comet – using browser connections
Comet is a web application model in which a long-held HTTP request allows a web server to push data to client browsers, without the browser explicitly requesting it. It works the way that the web browser requests an url from the server, and the server deliberately keeps it open, allowing it to work as a stream of data between the server and the client web browser. In this stream the web server can push content to the client.
Keeping connections open for such a long time is not how HTTP requests was intended to be used, so a lot of people have been describing this as a hack. The biggest problem with Comet has been that the HTTP 1.1 specification states that a web browser should not have more than two simultaneous connections to a web server. By using Comet, one of these connections would always be held open for push notifications. Only having one available connection could limit the browser. An example could be that the browser may be blocked from sending a new request while waiting for the results of a previous request while loading a series of images. Most sites solved this by creating a separate sub domain for the real time communication. Also, getting Comet to work properly in all web browsers isn’t at all trivial. So what other options are there?
Comet – using Flash sockets
Flash sockets is based on the same idea as Comet. On the server side it is very similar to the regular use of Comet, but on the client side the connection to the server is kept open by using a Flash Socket running in a flash application. Since the HTTP connection is opened by Flash it will work the same way in all web browsers, but the downside is of course that it requires Flash, so many mobile browsers will not be able to use it. The Flash socket implementation is considered as more stable and not as much as a hack as the browser Comet implementation. However, it is considered a temporary solution until most web browsers have implemented support for WebSockets.
WebSockets – The replacement for Comet
WebSockets is a technology for providing bi-directional, full-duplex communications channels, over a single TCP socket and is supposed to be able to replace the different Comet solutions that exists today. The API is being standardized by the W3C and is currently implemented in Chrome 4+ and Safari 5+. It is also implemented in Firefox and Opera, but disabled by default. As usual, Internet Explorer is lagging behind and no support for WebSockets exists as of today. Maybe in Internet Explorer 10, who knows… So it will be a while until WebSockets are so widely accepted that we can only rely on WebSockets.
On the server side
To allow for Comet connections the web server needs to support long lived HTTP connections. Most web servers were not built for this, so implementing Comet on a web server such as IIS can be a bit of a challenge, especially when scaling to lots of concurrent users.
Holding lots of concurrent connections open is something that Node.js is very good at (I blogged about Node.js a few weeks ago), and not supprisingly there are many Comet notification servers built on it. The two most popular implementations seems to be Juggernaut and Faye. Lets get into a crash course in how to start using Juggernaut.
Juggernaut is a push notification server for WebSockets with a easy fallback to Flash sockets if the clients web browser does not support it. Getting started with Juggernaut is very easy, I got my server up running in just a few minutes. Let me show you how to do it on OSX.
First, if you don’t already have Homebrew (a Unix package manager for OSX) installed, go ahead and install it:
$ curl -LsSf https://github.com/mxcl/homebrew/tarball/master | sudo /usr/bin/tar xvz -C/usr/local --strip 1
Now install Node.js, Redis (key/value data strore server, the Juggernaut server and the Juggernaut gem (if you want the Ruby support). Follow the instructions for each package.
$ brew install node
$ brew install redis
$ npm install juggernaut
$ gem install juggernaut
Now start Redis and Juggernaut:
$ redis-server &
$ node ~/node_modules/juggernau/server.js &
Now lets create an HTML file, jugtest.html, and host it on a local web server:
var jug = new Juggernaut;
Also, let’s create a simple Ruby script, test.rb, to send notifications:
Juggernaut.publish("channel1", "Hello world!")
Everything should be setup now, let’s browse jugtest.html, my webserver runs on port 3000, so for me that is http://localhost:3000/jugtest.html. Nothing shows up in the web browser, but in the terminal running Juggernaut we should be able to see that one client has connected. Lets run the ruby script:
$ ruby test.rb
The message shows up in the web browser, it works!
As you can see getting started with push notifications using Juggernaut is very easy. If you have any experience with other push notification servers, please leave a comment, it would be interesting to hear your experiences!