We’re starting a new feature comparing opposing perspectives. This time the subject is the Bayeux protocol and the general question of a standard for Comet.
Today, Greg Wilkins of Webtide and Jetty (and one of the writers of the Bayeux specification) talks about the need for a standard and how Bayeux fits this need. Tomorrow, Michael Carter of Orbited will raise some critical questions about Bayeux, to which Greg will respond to.
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
What the Problem Is
On one level, Comet is very easy: pick up your nearest XHR-for-dummies book, send a request to the server and wait for something to happen before sending a response.
Yet when you get into the details of Comet, it has some very difficult resource management issues that need to be dealt with. Most of these issues stem from the 2 TCP/IP connection limit imposed by RFC2616 for HTTP/1.1 for a HTTP client communicating with a given HTTP server.
The limit is applied to the entire client (i.e. browser) and not just to a given frame, tab or window. A single Comet connection consumes both of the available TCP/IP connections: one for the long poll or streaming response and another for any outgoing calls. Thus in an entire browser, only 1 Comet instance can be connected to a given host.
But there are many use-cases where it is easy for multiple Comet connections to be needed:
- Two frameworks on the same page independently implementing Comet
- A page with multiple frames, each with its own Comet instance
- Multiple tabs or windows pointing at the same web application
- Multiple Comet applications that have been mashed up together or combined by a portlet server.
Even without considering Comet, the semantics of XHR as used by Ajax also has some related resource limitations. If you have 10 widgets on a page that all need to update their state from the server, these requests have to be squeezed over the shared 2 connections. If the widgets use XHR wrappers to do this, then the user will have to wait for the latency of multiple round trips to the server as each of the 10 requests and responses queue up behind the two available connections.
Some people advocate the use of host name aliases to circumvent the 2 connection limit. But this is a false hope. 4 or 8 connections will soon be insufficient as we mashup more widgets onto a single page. But more importantly, the 2 connection limit is there for reason: to conserve expensive server resources. To double the connections from a single client is to halve the number of simultaneous users a server can handle.
But the good news is that dealing with limited resources is not an unfamiliar problem for computer science. After all, most computers have only 1 or 2 CPUs, and we manage to share those between many disparate processes. In order to share limited resources we use common infrastructure, libraries, and/or operation systems.
The only way we can share the scarce connections is to have a common infrastructure, but we will never agree on one and only one Ajax framework, and the frameworks themselves can’t even agree on a getElementById wrapper, let alone limiting and controlling access to XHR, script elements and anything else that may consume connections.
How Bayeux Addresses the Problem
So what does all this have to do with Bayeux? Isn’t it just another framework trying to be the one and only one? Well NO IT’S NOT.
Bayeux is not a framework, it is a specification.
And the Bayeux specification has two great strengths that will help us all get past the limited resources problem:
- Bayeux specifies a publish subscribe messaging semantic, which is a vastly better abstraction layer than XHR or request/response for achieving flexibility, scalability and resource sharing.
- Bayeux specifies that transport is negotiated between a client and server and that the details of that transport are a separate concern to the use of the Bayeux messaging layer.
Bayeux recognizes that we all have to agree on something if we are going to share the limited resources of the browser. But it also recognizes that we are not all going to agree on long polling or streaming, or on stopping innovation on new transports. So transport is negotiable in Bayeux.
Bayeux recognizes that we will not all agree on an API or even how callback and subscriptions etc. will be abstracted within a client and/or server. Thus multiple implementations and framework integrations exist and more are on their way.
Bayeux recognizes that not everybody is a JSON fan, and while the content of the Bayeux messages is specified in JSON, there is no requirement that they are sent as JSON, and implementations of XML (e.g. BOSH), binary, or telepathic transports would be welcome.
Bayeux recognizes that it has not solved all the problems. For example, the solutions for multi-tab are still very rudimentary and there is no support for inter-framework message bridges. However, Bayeux provides an environment in which innovation can strive for better solutions to these problems without requiring applications to be re-written.
So yes, I know the default transports may not be optimal for all use-cases. I know the Dojo client can be considered a bit fat, and I know the fast Java servlet only scales well on Jetty. I know we need to support inter-framework message bridges.
These are concerns that I share—but they are concerns that Bayeux separates from the application developer by a semantic divide. These are concerns that framework and server developers can innovate, differentiate and compete about.
Finally, the initial Bayeux implementations are provided by the Cometd project at the Dojo Foundation. While these implementations are not hugely mature, they have been developed by a team with real world experience of developing deployable and scalable web solutions. The Cometd implementation of Bayeux contains that experience as well as innovation and differentiation that allows it to be deployed reliably on today’s browsers, scale to enterprise levels and compete well with other Comet options out there on its own merits.