For CometD support, custom code development, clustering advices, scalability and performance tuning, contact the core CometD developers at www.webtide.com

Chapter 7. JavaScript Library

7.1. Configuring and Initializing
7.1.1. Configuring and Initializing Multiple Objects
7.2. Handshaking
7.3. Subscribing and Unsubscribing
7.3.1. Meta Channels
7.3.2. Service Channels
7.3.3. Broadcast Channels
7.3.4. Subscribers versus Listeners
7.3.5. Dynamic Resubscription
7.3.6. Listeners and Subscribers Exception Handling
7.3.7. Wildcard Subscriptions
7.3.8. Meta Channel List
7.4. Publishing
7.5. Disconnecting
7.5.1. Short Network Failures
7.5.2. Long Network Failures or Server Failures
7.6. Message Batching
7.7. JavaScript Transports
7.7.1. The long-polling Transport
7.7.2. The callback-polling Transport
7.7.3. The websocket Transport
7.7.4. Unregistering Transports
7.7.5. The cross-domain Mode

The CometD 2 JavaScript library is a portable JavaScript implementation with bindings for the major JavaScript toolkits, currently Dojo and jQuery. This means that the CometD Bayeux JavaScript implementation is written in pure JavaScript with no dependencies on the toolkits, and that the toolkit bindings add the syntactic sugar that makes the Bayeux APIs feel like they are native to the toolkit. For example, it is possible to refer to the standard cometd object using the following notation:

// Dojo style
var cometd = dojox.cometd;

// jQuery style
var cometd = $.cometd;

If you followed Chapter 5, Primer, you might have noticed that the skeleton project requires you to reference both the portable implementation, under org/cometd.js, and one binding - for example Dojo's - under dojox/cometd.js. For jQuery, the binding is under jquery/jquery.cometd.js. The use of the Bayeux APIs from the JavaScript toolkits is almost identical, and the following sections do not refer to a particular toolkit. Small differences surface only when passing callback functions to the Bayeux API, where Dojo users might use dojo.hitch(), while jQuery users might prefer an anonymous function approach.

The following sections present details about the JavaScript Bayeux APIs and their implementation secrets.

7.1. Configuring and Initializing

After you set up your skeleton project following Chapter 5, Primer, you probably want to fully understand how to customize and configure the parameters that govern the behavior of the CometD implementation.

The complete API is available through a single object prototype named org.cometd.Cometd. The Dojo toolkit has one instance of this object available under the name dojox.cometd, while for jQuery it is available under the name $.cometd. This default cometd object has been instantiated and configured with the default values and it has not yet started any Bayeux communication.

Before the cometd object can start Bayeux communication it needs a mandatory parameter: the URL of the Bayeux server. The URL of the server must be absolute (and therefore include the scheme, host, optionally the port and the path of the server). The scheme of the URL must always be either "http" or "https". The CometD JavaScript implementation will transparently take care of converting the scheme to "ws" or "wss" in case of usage of the WebSocket protocol.

One cometd object connects to one Bayeux server. If you need to connect to multiple Bayeux servers, see Section 7.1.1, “Configuring and Initializing Multiple Objects”

There are two ways of passing the URL parameter:

// First style: URL string
cometd.configure('http://localhost:8080/cometd');

// Second style: configuration object
cometd.configure({
    url: 'http://localhost:8080/cometd'
});

The first way is a shorthand for the second way. However, the second way allows you to pass other configuration parameters, currently:

Table 7.1. JavaScript Library Configuration Parameters

JavaScript Library Configuration Parameters
Parameter NameRequiredDefault ValueParameter Description
urlyes The URL of the Bayeux server this client will connect to.
logLevelnoinfoThe log level. Possible values are: "warn", "info", "debug". Output to window.console if available.
maxConnectionsno2 The maximum number of connections used to connect to the Bayeux server. Change this value only if you know exactly the client's connection limit and what "request queued behind long poll" means.
backoffIncrementno1000 The number of milliseconds that the backoff time increments every time a connection with the Bayeux server fails. CometD attempts to reconnect after the backoff time elapses.
maxBackoffno60000 The maximum number of milliseconds of the backoff time after which the backoff time is not incremented further.
reverseIncomingExtensionsnotrueControls whether the incoming extensions are called in reverse order with respect to the registration order.
maxNetworkDelayno10000The maximum number of milliseconds to wait before considering a request to the Bayeux server failed.
requestHeadersno{} An object containing the request headers to be sent for every Bayeux request (for example, {"My-Custom-Header":"MyValue"}).
appendMessageTypeToURLnotrue Determines whether or not the Bayeux message type (handshake, connect, disconnect) is appended to the URL of the Bayeux server (see above).
autoBatchnofalse Determines whether multiple publishes that get queued are sent as a batch on the first occasion, without requiring explicit batching.
connectTimeoutno0 The maximum number of milliseconds to wait for a WebSocket connection to be opened. It does not apply to HTTP connections. A timeout value of 0 means to wait forever.
stickyReconnectnotrue Only applies to the WebSocket transport. Determines whether to stick using the WebSocket transport when a WebSocket transport failure has been detected after the WebSocket transport was able to successfully connect to the server.

After you have configured the cometd object, the Bayeux communication does not start until you call handshake() (see Section 7.2, “Handshaking”).

Previous users of the JavaScript CometD implementation called a method named init(). This method still exists, and it is a shorthand for calling configure() followed by handshake(). Follow the advice in Section 7.2, “Handshaking” as it applies as well to init().

7.1.1. Configuring and Initializing Multiple Objects

Sometimes there is the need to connect to multiple Bayeux servers. The default cometd object available as dojox.cometd or $.cometd can only be configured to connect to one server.

However, it is easy to create other cometd objects. In Dojo, there is a dojox.Cometd (note the capital 'C' of Cometd) constructor function that can be used to create new cometd objects. In jQuery, there is an equivalent $.Cometd constructor function. It can be used in this way:

// Dojo style
var cometd1 = dojox.cometd; // The default cometd object
var cometd2 = new dojox.Cometd(); // A second cometd object

// jQuery style
var cometd1 = $.cometd; // The default cometd object
var cometd2 = new $.Cometd(); // A second cometd object

// Configure and handshake
cometd1.init('http://host1:8080/cometd');
cometd2.init('http://host2:9090/cometd');

Note how the two cometd objects are initialized with different URLs.

7.1.1.1. Configuring Extensions in Multiple Objects

Configuring extensions in the default cometd object is covered in Chapter 9, Extensions. To configure extensions for the additional cometd objects must be done manually in the following way:

// Dojo style
var cometd1 = dojox.cometd; // The default cometd object
var cometd2 = new dojox.Cometd(); // A second cometd object

// jQuery style
var cometd1 = $.cometd; // The default cometd object
var cometd2 = new $.Cometd(); // A second cometd object

// Configure extensions for the second object
cometd2.registerExtension('ack', new org.cometd.AckExtension());
cometd2.registerExtension('timestamp', new org.cometd.TimeStampExtension());
cometd2.registerExtension('timesync', new org.cometd.TimeSyncExtension());
cometd2.registerExtension('reload', new org.cometd.ReloadExtension());

You should not configure the extensions for the default cometd object in this way, but instead follow Chapter 9, Extensions.

You should configure extension manually like shown above only for additional cometd objects. You can configure zero, one, or all the extensions for the additional cometd objects, depending on your application needs.