Avoiding long polling

Posted on July 26, 2009

Right from Twitter to Google Wave, real time information streaming via the browser seems to be the most "happening" thing on the web arena currently. However, feeding real time information as and when it is available to an user using your web application is not as straight forward as it is on a desktop environment. HTTP is a stateless protocol which does not currently support a two way communication link between the server and the user’s computer via the browser.

The simplest way to simulate real time streaming of information is to poll the server every N seconds, and to display the information (if any). The number N will determine how real time the resulting stream of updates will look to a viewer. This model is simply called, polling. Now, polling is bad because it repeatedly connects and disconnects to the server, which when scaled across thousands of users, cause severe strain on your server. This problem becomes even more apparent in cases when the poller returns with empty data most of the times.

The jQuery snippet below polls the server every 3 seconds for new information and displays it in a simple alert box.

function callComplete(response) {
	alert("Response received is: "+response);
};

function connect() {
	// when the call completes, callComplete() will be called along with
	// the response returned
	$.post('/path/to/script.php', {}, callComplete, 'json');
};

$(document).ready( function() {
	setInterval(connect,3000);
}

Long polling

This technique is an optimisation of the traditional polling method. In long polling, once the client makes a connection with the server (via JavaScript), the server waits for the data requested by the client to become available. If it’s not immediately available, the server (being a PHP script for example) loops and sleeps. When the data is available, the server returns the data to the client and the connection closes. When this happens, the client again reconnects with the server (in the callback function of your original AJAX request).

This method is definitely an improvement over mindless polling, as we will avoid repeatedly opening and closing connections when data is not available for long periods of time. However, it is important to be aware of the server side technical limitations of long polling. Since connections might be kept alive for long durations of time, your web server must be capable of handling such large numbers of simultaneous connections. We talked about how certain light weight webservers outperformed Apache in this particular area in the last article.

Let’s look at a very simple jQuery/PHP long polling example:

function callComplete(response) {
	alert("Response received is: "+response);
	// reconnect to the server
	connect();
};

function connect() {
	// when the call completes, callComplete() will be called along with
	// the response returned
	$.post('/path/to/script.php', {}, callComplete, 'json');
};

$(document).ready( function() {
	connect();
}

In the PHP end, we do:

while(1) {

	$data = "some data fetched from the DB";

	// if we have new data, return it to the client
	if(!empty($data)) {
		echo json_encode($data);
		break;
	}

	sleep(3000);	// we sleep for 3s and check again for data
}

COMET streaming

COMET is a generic term that refers to the use a persistent HTTP connection for the web server to "push" data to the client as and when it arrives. If you have ever wondered how Gmail is able to notify you of a new email message seconds after it is sent, this is what they use to push the new email notifications to the front end.

However, as often is the case with JavaScript, the cross browser compatibility issues mean that a host of methods (targeting different browsers) are used to implement such an interaction. The upside is that these methods rely purely on JavaScript, and hence not dependent on any specific client side plugin. A detailed exploration of these different methods and their caveats is beyond the scope of this article, but let’s get a quick overview of these methods.

Hidden iframe technique: A hidden iframe html element is embedded onto the page, which points to the URL on the server which handles the persistent connection. The server will then push the data as it arrives to the iframe, using <script> tags. This content is then channeled to the parent window using JavaScript. This method is based on the fact that many browsers evaluate JavaScript chunks as they are received, even if the complete page has not finished loading yet. However this method is prone to cause the "loading" icon or status bar message to appear all the time (since we are using a persistent HTTP connection, the browsers tend to believe that the page is yet to finish loading fully).

XMLHttpRequest using Interactive readyState: This method is targetted towards Firefox, Safari and Chrome, which support the interactive readyState property of the XHR object, and fires events every time a chunk of data is received from the server.

Server-Sent events: This is a feature (from the WHATWG Web Applications 1.0 specification) supported by Opera since v9, using which we can push events from the server directly to the visitor’s browser. Refer to this article on how it’s used.

As you can see, it’s quite a mouthful, and hence implementing COMET streaming which works uniformly across all major browsers is not a task for the faint hearted (not forgetting that the webserver must also be able to handle a large number of persistent connection). The good news is that quite a lot of the hard work has already been done for you. There are various opensource COMET servers and client libraries which you can use to deploy a COMET application pretty safely. Here are a few of them for your exploration:

Orbited: "Orbited is an HTTP daemon that is optimized for long-lasting comet connections. Orbited allows you to write real-time web applications, such as a chat room or instant messaging client, without using any external plugins like Flash or Java. "

Cometd: "Cometd is a scalable HTTP-based event routing bus that uses a Ajax Push technology pattern known as Comet."

Meteor: "Meteor is an open source HTTP server, designed to offer developers a simple means of integrating streaming data into web applications without the need for page refreshes."

Comet Pi: This is a standalone JavaScript library which you can use to handle the various cross browser issues that COMET causes. You can use pi.comet with any serverside language.

Tags: , , , , ,

2 Responses

  1. [...] nice explanation of long polling and other [...]


  2. [...] nice explanation of long polling and other [...]


Leave a Reply

You must be logged in to post a comment.