For anyone who’s curious how Gmail’s chat widget notifies your browser that a new message has arrived, be curious no longer: here’s a simplified page that [demonstrates the method used](http://sandbox.mikepurvis.com/js/openget/).
Note: Before we go on, I should just clarify that nothing here is based on insider knowledge of Google (I was never anywhere near the Gmail code), and any opinions expressed are mine alone.
This demo itself is of interest to technical folks, because it demonstrates a way for programmers to work around another frustrating limitation that arises from the architecture of the web—that when an interaction over http takes place between a client (browser) and a server (website), the client must always be the one initiating the connection.
Update: In the comments, Rob has pointed out that this technique is part of an umbrella term “[Comet](http://cometdaily.com/),” which generally describes techniques for pushing data to the browser. [Simon Willison has more](http://simonwillison.net/2007/Dec/5/comet/).
But how does Gmail—and this demo—get almost instant notification? To achieve that responsiveness with polling has serious scaling issues. (Remember, even if a polling request basically returns nothing, there’s an overhead that accumulates from re-sending the headers on each poll. You can get a sense of this cost using a tool like [LiveHTTPHeaders](http://livehttpheaders.mozdev.org/).)
The strategy, in a nutshell, is that the request for new messages is made immediately, and the server simply holds the connection open and doesn’t answer *until it has something to say*. But before moving on to that, a diversion.
### Story Time
Except for one thing. What if a player wants to trade with you? The server needs a way of notifying the player that they have a pending trade offer. Polling on a 1- or 2-second period would have been adequate for that, but as I slept on it, it occurred to me that it should be possible to simulate a “push” just by having the server sit on the open connection until it had data to send.
As it turned out, we lost interest in the project, and I never pursued the idea for pushing data to the browser. Later, I would also realise that trying to use the browser’s scrollbars was foolish; when Google Maps launched, it became obvious that grab-and-drag was the right model for navigating a 2-D space in the browser.
When Gmail launched chat, I think I just assumed there was a hidden flash movie or something that made the magic happen.
That is, until just last week, now at RIM, when I was chatting with a colleague about how the BlackBerry receives push email. Now, obviously, the phone network is set up so that each device can receive push data—the phone ringing is a “pushed” event. But the BlackBerry is special among mobile phones in that it also receives *email* pushed. When other phones do email (until recently, anyways), they have to poll a server to check for messages… polling that costs battery life and network traffic.
We started discussing push to browsers, and someone mentioned about the new version of Gmail using a dangling GET connection to receive chat messages, and there it was. I don’t know if the older version did it this way or with polling, but as far as I can tell with Firebug, Gmail receives all server notifications (chat events and new emails, basically) through the same open-get stream.
And, of course, Google Docs (formerly Writely) uses the same trick to receive changes to a document as multiple authors collaborate on it.
### How It Actually Works
As with many paradigm shifts, this one exposes an interesting limitation in the existing tools—in this case, PHP. The only way for one request in PHP to communicate with another is through a shared common resource such as a file or the database connection. In my case, I used a file, called messages.csv. This is horribly bad, since you end up with legions of get.php requests all polling that file waiting for changes. Obviously bad and unscalable, but good enough for a proof of concept. A production implementation of this would need to run on server software capable of passing messages between requests.
JS guru Douglas Crockford calls this concept “duplexing” in a 2006 proposal for a [JSONRequest browser service](http://www.json.org/JSONRequest.html). So the idea is out there in the public space… at this point I’m just curious to see where else it can go. Ultimately, it’s applications that need the instant notification, but also require aspects of normal browser behaviour that Flash is unable to provide. Google has nailed the top two with a mail client and collaborative document editor, but I can’t help thinking that there’s at least a few other neat products that could be built around this kind of notification system.