Publishing and subscribing to server events from an Ajax client

Web-based interactions are synchronous. To receive content from a server, a request must be initiated by a browser. This process is sufficient for most Web-based interactions. However, there might be times when the content that the Web browser needs is not immediately available and is sent later. Some examples of this scenario include:
The browser has options to receive events from a server. For events and information that arrive immediately, the browser can initiate a request and wait for a server to receive the event. That process can take time, and does not guarantee that a connection can stay open long enough for completion notification, therefore it is not a useful solution. The next option, one widely used, is to poll the server for notification status. This process is an efficient mechanism when waiting for a single notification to complete. Consider what happens when the entire Web page is built on waiting for server events. You can still use Web-based polling; however, you must trade off between event latency and server load. Setting the polling interval to a high rate provides optimal event receipt latency; however, server load is high, accordingly. Alternatively, setting the polling interval to a low rate has a lower impact on server load. However, the time to receive events at the browser might not be acceptable. A time-based diagram showing browser polling is presented in following example:

Web based polling


Some methods can receive server-to-browser pushed events as an alternative to Web-based polling. These methods are based on a long-lived browser-to-server request. Long polling is one method that uses a long-lived connection. Long polling typically takes the form of an XmlHttpRequest request from the browser. If an event is ready when the request reaches the server, then the response is sent, and the connection is closed. The client then re-opens a request to the server to retrieve more events. If no event is ready to send, then the server holds the connection for a specified time, 30 seconds for example, and then closes the connection. The browser then re-opens the request and the cycle continues. The XmlHttpRequest connection must be closed immediately after the event is sent to the client so that the client can process the events. Because the connection must be closed to immediately process an event, followed by a reconnect, a long-poll connection cannot be considered a true asynchronous server push mechanism. The following diagram shows client and server interaction in a long-poll request:

Web-based polling


Another option similar to long polling is streaming: forever frame or true comet streaming. Streaming is similar to long polling except that this process uses an Iframe for communication and is truely asynchronous. Communication through an Iframe allows events to process in real time in the browser through JavaScriptTM tags. Multiple events can be sent before the HTTP connection needs to close. Streaming does have one restriction. Some proxies and firewalls buffer response content until the connection is closed. When content is buffered, events are no longer sent in real time, and are processed when the server closes the connection. The following diagram shows client and server interaction in a streaming request:

Web based polling


One major consideration when designing a Web site that employs a long-lived connection is the two connection per host name limit for some browsers. With one connection typically always connected to a server waiting for an event, you are likely restricted to one long-lived connection to a given host name. You cannot open two browser windows to the same host name with long-lived connections and open a third connection to same server, which includes XmlHttpRequest requests. Because of the two-connection limit and the source policy of the browser (XHR requests must go back to server the page that is originated from. This is due to the same domain security restriction of web browsers), there is interest in cross domain server event solutions to help alleviate the two-connection limit. With a cross domain solution, server events are received from a different host name than the one where the main HTML page is issued.

Different mechanisms process server-pushed events. You can use JavaScript to parse data from an XHR request in a long-polling request, and JavaScript tags are the mechanism used to achieve instant updates in a streaming request. Using an existing JavaScript toolkit can make event processing much easier. Multiple options are available when choosing a JavaScript toolkit, but one toolkit that provides Web publish and subsribe capabilities is the Dojo Toolkit. Recent versions of the Dojo Toolkit include a client module that communicates with a server for Web-based publish and subscribe capabilities. This module is called cometd, and it communicates through the Bayeux protocol. The Bayeux protocol supports long-polling XHR and cross domain callback transports. The Bayeux protocol can also be extended to support other transports, such as streaming (Iframe) or multipart Multipurpose Internet Mail Extensions (MIME) communication. Incoming events link directly into the Dojo event and topic system for simple yet robust presentation capabilities.

Dojo Toolkit

The Dojo Toolkit cometd client supports server-to-browser event push. On the client side, a Dojo application must include the cometd.js JavaScript file. When the cometd.js file is included, the cometd client must be initialized and then the application can subscribe, unsubscribe, publish to topics, and receive events. Incoming events link directly into the Dojo event and topic system. The cometd client communicates through the Bayeux protocol with a Bayeux enabled server. For more information on server setup, refer to the Web messaging service documentation. This IBM® technology, Web messaging service, provides a Bayeux server implementation. A sample QuoteStreamer application that uses the Web messaging service and Dojo Toolkit is also available. The following examples show the Dojo Toolkit and cometd client in use: