Note: Andrew’s article wasn’t written as part of the Colliding Comets: Bayeux series, but this article would be of interest to anyone following the Bayeux series:
Part 1: Greg Wilkins explains the need for Bayeux
Part 2: Michael Carter criticizes the current state of Bayeux
Part 3: Greg Wilkins responds to Michael Carter
Andrew Betts’ thoughts (from a related article)
Part 4: Michael Carter responds to Greg Wilkins
Part 5: Kris Zyp’s thoughts
Part 6: Alex Russell responds to Michael Carter
Part 7: Michael Carter responds to Alex Russell
In the late 1950s, when the US and the Soviet Union began manned space programmes in earnest, they both encountered a problem: pens don’t work in space, because a force is required to carry the ink to the nib, and that force is normally gravity. NASA therefore embarked on a research programme to develop pressurised ink cartridges that would work in space. Many millions of dollars later, they perfected the space pen. This revolutionary piece of technology features a tungsten carbide ballpoint precisely engineered to avoid leaking ink, and a float to keep the ink reservoir separate from the pressurised nitrogen that forces it out at any angle. The pen can also write at extreme altitude, on greasy surfaces and at extreme temperatures.
Meanwhile, the Russians used pencils.
Yes, it’s inelegant, a bit messy, doesn’t do much for the cause of human knowledge, but if we’re trying to solve the problem of writing in zero gravity, then job done.
I think this is a great story (despite the fact that, sadly, it isn’t true), because it demonstrates the tendency for engineers to occasionally invent a solution to a problem that doesn’t exist, or to solve a symptom rather than a cause. Others can identify the easy way and grasp what I call the ‘pencil solution’.
The particular problem Comet is trying to solve is pushing data from server to client in an event driven way, and doing so in a way that works in most web browsers, so it can be used on a website. We currently achieve this by making an HTTP connection, but while HTTP is designed to transport hypertext in a stateless, non-persistent way, we’re using it to transport (typically) JSON or XML in a stateful, persistent way. Sounds rather like trying to shove a square peg in a round hole, which is exactly what it is.
Added to that, each browser presents a need for a different implementation strategy which leads us to a series of hacks that differ from one browser to the next.
Ideally, since we’re generally transporting a data stream, and doing so on a persistent connection, it would make sense for there to be a protocol designed from the ground up for this that all browsers support in a consistent way. Some work has gone into this in the WHATWG and W3C HTML working group, with ‘server-sent DOM events‘ a feature of the upcoming HTML 5 specification, and already partially implemented in Opera. However, the spec for this feature still envisions developers using regular HTTP to send event streams, and makes only this passing reference to other protocols:
For non-HTTP protocols, UAs should act in equivalent ways.
Is HTTP coming to be seen as a Swiss army knife for any kind of vaguely web-related data transport requirement? Any application protocol built on top of HTTP accepts as a fundamental principle that at the transport level, the protocol is a stateless request-response system. The Bayeux spec pays similar attention to non-HTTP protocols as server-sent events does:
Other transports that support a request/response paradigm may be used. However this document assumes HTTP for reasons of clarity.
So what I’m saying here is that in creating this kind of protocol that builds on top of HTTP, you essentially rule out the possibility of using any transport protocol that is not implemented as a request-response paradigm. As I try to keep up with the debate my co-contributors are having (part 1 here) about Bayeux, this is one of the main issues that troubles me. Why choose a transport protocol that’s so apparently misaligned with the purpose of the system, and then create an application protocol on top of it that corrects for the misalignment.
The obvious answer is that Comet is about communication with a web browser, and that means speaking in HTTP, and so right now this is the best we can do. But when browsers don’t understand the protocols we want natively, traditionally that’s what plug-ins are for. If you start with the objective of eliminating plug-ins, that means accepting a big fudge of browser inconsistent hacks, plus limitations that you just can’t work around, like cross-domain streaming and multiple concurrently connected clients. These are not small problems.
Of course the perfect solution is that mythical transport protocol that all browsers support in the same way and which is designed to do exactly what we’re trying to achieve with Comet. And if re-engineering at the transport level is too much to ask, at least server-sent events might offer a standardised application protocol that can be implemented consistently.
Of course you still need a server that supports event streaming on long-lived connections, but the unsavoury client-side of comet suddenly becomes simple. It also trivially solves all cross-domain issues, needs no headers or JSON encoding, and works using the same technique on all browsers that support Flash player 6 or greater.
What about mobile. Well, push-to-mobile is a problem solved as long ago as 1999 by Research in Motion. Their Blackberry devices work so well that the prospect of losing the service thanks to a patent dispute was very nearly ruled a national emergency in the US. The reason these things Just Work is that RIM has control of everything: server software, client software, client OS, even the handset hardware can be designed to work together. It’s one great big happy family of closed source proprietary technology. But imagine a mobile Comet web app providing a user experience anywhere near as good as a Blackberry’s native email client. Web browser running in background constantly??? Even then, you’ve got no access to the phone’s OS to fire vibration or audio alerts. Even if Comet worked perfectly (using any transport), lack of support for Flash would be the least of your problems when it comes to mobile push.
Here’s a video (the Flash bit is the tiny 30×15 widget at the top right of the scrolling DIV):
(Note that the periodic disconnects are being forced at the server end to test client resilience).
Heady with excitement, I got carried away and stuck six of them on the same page, and in doing so proved that I could stream from multiple completely alien domains simultaneously and maintain at least four concurrent connections to the same one. The client also implements auto-reconnect, doesn’t require any padding on the response, and just needs a null byte to separate packages. The bandwidth use is a fifth of the equivalent payloads sent using Bayeux. The ActionScript weighs in at 3KB uncompressed and the finished SWF, even incorporating a simple UI, is a tiny 2.3KB.
Bayeux actually acknowledges the potential of using a Flash client in the spec, but this is surely nonsense, as virtually none of the reasons you might want to use Bayeux apply when you’re building on a client than can make its own raw socket connections.
So in summary I’m saying it could be argued that Bayeux is a solution looking for a problem. Flash combined with a protocol built directly on top of TCP/IP is smaller, leaner, more compatible, less restrictive, and simpler. While not everyone is going to be satisfied with that, it’s certainly a perfectly respectable alternative. And when you have several possible (imperfect) ways of solving a problem (and probably more on the way) standardising on one of them just seems to limit choice. I agree with Michael Carter’s recent post that if we are to standardise anything, it should be the API, not the communication protocol.
So we wait…for the holy grail of standardised server-pushed events in HTML 5, if indeed it materialises. And in the interim, no one imperfect solution seems any better than any other imperfect solution. Now where did I put that pencil…