CometD - Features and Limitations

CometD is an open source HTTP-based event routing bus that uses a Ajax Push technology pattern known as Comet.

These are some of the features provided by CometD:

Client Side:

  • Written in Javascript. Whole API available thru a single object prototype called org.cometd.Cometd
  • First step - Configure this object with the URL of the Bayeux Server. We can also pass in optional parameters such as backOffIncrement, maxBackoff etc
  • Next step - Handshake. This initiates a connection with the Bayeux Server
  • Listener vs Subscriber --> Synchronous and asynchronous respectively. Listeners are used to receive meta messages (these channels are set up by the implementation), so listeners can be used to receiver handshake errors. Subscription is used for normal channels. Cometd provides certain default meta channels (meta/connect/, meta/disconnect, meta/handshake etc) which can be listened to to get information about connection status
  • Subscription to a normal channel can be controlled by implementing a security policy at the server
  • Client-side optimization: Batch messages to utilize network resources more efficiently
  • Has the ability to handle cross-origin requests - uses JSONP to get around same-origin policy
  • Allows extensions which are basically functions that can be invoked at certain points of a message's lifecycle such as just before sending a message or just after receiving a message
  • Provides different 'channels' for different kinds of data. A channel is just a string. The underlying transport for all messages is the same. When a message arrives, it looks for the 'channel' property, finds the appropriate listeners (callbacks) from a hash and invokes them.

Server Side:

  • Client identified by a unique client_id that comes with every message. This client id is used to retrieve an appropriate session object
  • Uses an implementation of the Continuation interface, which is a mechanism by which a HTTP Request can be suspended and restarted after a timeout or an asynchronous event has occurred. This comes bundled with Jetty Web Server, which Cometd uses. According to the API, the implementations release the thread while it is waiting for new messages to arrive
  • Does housekeeping to ensure a bounded number of outstanding requests from each browser. Also cleans up old requests periodically
  • ServerSession - Server side representation of clients. These can 'subscribe' to a ServerChannel and get all messages published on that channel
  • Every ServerSession maintains a set of channels it is subscribed to
  • Server side SecurityPolicy and Authorizers can be used to control which ServerSession objects can subscribe to which ServerChannels
  • Local Sessions are the same as Client Sessions except that they exist on the server (ie. local to the Bayeux Server instance)

Other techniques for implementing a server 'push':

Websocket API - Originally part of HTML5 specification. It provides two-sided communication with a remote host. It is now supported natively in Google Chrome.

CometD on a cluster:

  • Cometd servers may be aggregated into a cluster using Oort, which is a collection of extensions that use the java CometD client to link the servers together. The Oort class allows cometd servers to observe each other, which means to open bayeux connections in both directions.
  • Every comet server creates an instance of Oort which creates a BayeuxClient (called an OortComet) to connect to all other known comet servers (These URLs must be passed to the Oort object during instantiation). It then adds listeners to whatever channels it is interested in. Thus, each server communicates both ways with each other server in the cluster.
  • There is a special set of channels, "/oort/*" for cluster communication. There is a special channel called '/oort/cloud' on which comet servers can broadcast the URLs of comet servers they know of.
  •  Seti is used to send messages to a user on a different comet server.
    • There is one Seti instance on each server
    • When a new user logs into a comet server, it creates an entry associating its Id with a ServerSession object. Additionally, it broadcasts on special channel called '/set/ALL' telling every other server that this user exists and is connected to this server and can be reached on a direct channel to this server
    • When a message meant for a particular user is sent, a server first checks local sessions to see if it has the client connected to it, otherwise it broadcasts the message on '/seti/ALL'
    • They are trying to introduce an intermediate level of 'shards' of comet servers, but haven't implemented that in version 2.0.0. The idea is that when a new user logs into one comet server, this piece of information is broadcast to this shard and not on '/seti/ALL'. Furthermore, when a message is sent out, it is sent to one comet inside each shard. If that comet cannot find the user in it's local connections, it broadcasts the message to its entire shard.