Seventh Octave

We're Starters. We write about culture, design and the business of software.

We believe software should be beautiful and inspired. Follow us as we build @TechOctave.

Simple Long Polling Example with JavaScript and jQuery TVD Oct 15

14 comments Latest by TVD

There are many reasons you might need to poll a web server. Recently, one of our Dashboard Gauge Suite customers needed to poll sales data from his company's data warehouse and update his executive dashboard with the fresh data.

But you could be doing something different too. Maybe you're pulling your company's QC data so you can give your leadership team a visual of how each group is managing defect counts.

Advanced JavaScript Long Polling Techniques (Server Push Techniques)

These two scenarios each have three things in common. First, a passion to display data in a beautiful and familiar way. Second, a desire to update each gauge without refreshing the page. Finally, each needs a smart and efficient way to poll their respective servers.

Here, we're going to accomplish each commonality with an emphasis on polling options and techniques:

A History of Polling

Realtime web applications have been with us for quite some time now. To the end user, these applications feel responsive and fluid. Gmail is (arguably) one of the most major applications to popularize this technique. JavaScript is at the heart here.

Have you ever been in the middle of replying to an email, when (suddenly) you're notified the person has sent you another followup? That's the perfect example of polling - sometimes referred to as server-push or comet technology.

A Tale of Two Polling Techniques

Traditional Polling

The setInterval Technique

Now, if you needed to poll your web service, your first instinct might be to do something like this with JavaScript and jQuery:

setInterval(function(){
    $.ajax({ url: "server", success: function(data){
        //Update your dashboard gauge
        salesGauge.setValue(data.value);
    }, dataType: "json"});
}, 30000);

Here, we have the poll ready to execute every thirty (30) seconds. This code is pretty good. It's clean and asynchronous. You're feeling confident. Things will work (and they will), but with a catch. What if it takes longer than thirty (30) seconds for the server to return your call?

That's the gamble with using setInterval. Lag, an unresponsive server or a whole host of network issues could prevent the call from returning in its allotted time. At this point, you could end up with a bunch of queued Ajax requests that won't necessarily return in the same order.

The setTimeout Technique

If you find yourself in a situation where you're going to bust your interval time, then a recursive setTimeout pattern is recommend:

(function poll(){
   setTimeout(function(){
      $.ajax({ url: "server", success: function(data){
        //Update your dashboard gauge
        salesGauge.setValue(data.value);

        //Setup the next poll recursively
        poll();
      }, dataType: "json"});
  }, 30000);
})();

Using the Closure technique, poll becomes a self executing JavaScript function that runs the first time automatically. Sets up the thirty (30) second interval. Makes the asynchronous Ajax call to your server. Then, finally, sets up the next poll recursively.

As you can see, jQuery's Ajax call can take as long as it wants to. So, this pattern doesn't guarantee execution on a fixed interval per se. But, it does guarantee that the previous interval has completed before the next interval is called.

Both techniques suffer from the same flaw - a new connection to the server must be opened each time the $.ajax method is called. To make that connection, your realtime app must gear up and battle through hoards of competing network traffic to make it to your server.

What if you could just keep the connection open?

Long Polling - An Efficient Server-Push Technique

If you could simply keep the connection open, then your application would see faster response times and appear more responsive. That's a good thing and that's where Long Polling comes in:

(function poll(){
    $.ajax({ url: "server", success: function(data){
        //Update your dashboard gauge
        salesGauge.setValue(data.value);

    }, dataType: "json", complete: poll, timeout: 30000 });
})();

Complete: A function to be called when the request finishes (after success and error callbacks are executed). In this case, we call our JavaScript poll function and restart the polling process.

Timeout: Set a timeout (in milliseconds) for the request. The timeout period starts at the point the $.ajax call is made. Here, we set the timeout to 30 seconds. This means our poll function won't get called again until both the ajax call is complete and (at-least) thirty (30) seconds have passed.

As you can see, the Long Polling technique combines the best-case traditional polling with persistent remote server connections. The term Long Polling itself is short for long-held HTTP request.

Applications built with Long Polling in mind attempt to offer realtime interaction, using a persistent or long-lasting HTTP connection between the server and the client.

The self executing JavaScript poll function combined with jQuery Ajax's repeating timeout interval means this is a very efficient server-push technique.

See, comments for further discussion on this technique. Thanks!

What's next? HTML5 WebSockets.

These types of Ajax Push techniques set the foundation for HTML5 WebSockets. With HTML5 WebSockets, we'll be able to see true Server Push styles of application development. This will make for truly responsive web applications.

Lately, I've been recommending Socket.IO for just such the occasion. Think of Socket.IO as the jQuery of HTML5 WebSockets.

No two browser vendors will implement the WebSockets protocol exactly alike. Socket.IO tries to normalize those differences. Here's how you might use Socket.IO with our Dashboard Gauge Suite:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect("http://localhost");
  socket.on('sales', function (data) {
    //Update your dashboard gauge
    salesGauge.setValue(data.value);

    socket.emit('profit', { my: 'data' });
  });
</script>

In order to provide realtime connectivity on every browser, Socket.IO selects the most capable transport at runtime, without it affecting the API. If WebSockets are available, it will use WebSockets.

If WebSockets aren't available, Socket.IO will select the next best transport including: Adobe Flash Socket or Ajax Polling. So having a solid understanding of JavaScript Long Polling examples is crucial.

We're still some time off before WebSockets will be universally and consistently supported. Until then, the jQuery Long Polling technique is a best-in-class solution for realtime server communications.

Eat, Pray and Code

Long polling addresses the weakness of traditional polling by keeping the connection to your server open. Keeping the connection to the server open eliminates the travel time from client to server and thus, significantly reduces the issues surrounding network latency.

If you're looking for a beautiful suite of dashboard gauges for your next business intelligence project, I encourage you to check out our Dashboard Gauge Suite. And if you need an accompanying Polling solution, please do give the jQuery Long Polling solution a try.

We also sell a beautiful set of JavaScript Charts in our JavaScript Charts Suite. It's easy to get started, with a powerful API when you need it.

If you enjoyed this post, subscribe for updates (it's free).

Email Address:

14 comments so far

Austin 27 Dec 11

Wow, great article. Thanks for this!

TVD 27 Dec 11

@Austin You're Welcome! Go forth and build something awesome!

Szilárd Szakács 24 Jan 12

How do you stop long polling? I use jQuery Mobile and I only want to update the currently active page. I would like to start polling on the pageshow event and stop it on pagehide.

TVD 25 Jan 12

@Szilárd: Sound like a really neat project. Based on your needs, I'd recommend you try the The setInterval Technique. You'll need to save the intervalId: //Start polling on the pageshow event var intervalId = setInterval(function(){ $.ajax({ url: "server", success: function(data){ //Update your dashboard gauge salesGauge.setValue(data.value); }, dataType: "json"}); }, 30000); //Stop polling on the pagehide event clearInterval(intervalId); Because the other techniques use self executing closures, they may not be the best fit. These closures limit object scope to the closure block: (function(){ var intervalId = 123; console.log(intervalId); => 123 })(); console.log(intervalId); => 'undefined' What this means is - with the other techniques - intervalId will be 'undefined' when the pagehide event is called and you won't be able to stop polling. Give setInterval a try!

A. Sinan 30 Jan 12

Hi, i am trying to create a wall like thing where ppl will get signed in and comment on, i jst read about "long polling" i was wondering if there are any examples for a wall like thing for this where all the online members can see in real-time, if something is updated on the wall on that specific page.

TVD 30 Jan 12

@A. Sinan: Sky's The Limit really . . . Checkout Peerbind.js - It's a super simple JavaScript API for doing peer-to-peer communication on a site with no need to set up a server. Have a friend join you on the site for maximum exploration. Then there is SignalR from Scott Hanselman, David Fowler and crew. SignalR is an Async signaling library for .NET to help build real-time, multi-user interactive web applications. Inevitably, each of the projects mentioned fall back to JavaScript Long Polling when no other viable transport mechanism is available (e.g. WebSockets not available). So, I'd say grab your favorite JavaScript Long Polling technique mentioned above, sprinkle in your favorite server-side framework and have some fun!

Lars 09 Feb 12

I am not convinced the long polling code is correct, because i just tried it. Specifically, are you sure the timeout param in $.ajax works that way, i.e. to delay the next execution by at least 30 seconds? Because i think it just sets a maximum timeout for the call. When I tried it just now the function kept firing AFAICT as fast as it could loop. The example above it, with setInterval, works as expected.

TVD 09 Feb 12

@Lars: From the jQuery API:
timeout: Set a timeout (in milliseconds) for the request . . . The timeout period starts at the point the $.ajax call is made; if several other requests are in progress and the browser has no connections available, it is possible for a request to time out before it can be sent.
The timeout option indeed doesn't delay the next execution for X seconds. In fact, I think you are correct in that it only sets a maximum timeout for the current call. Better to use setTimeout to set the interval then. Maybe something like: (function poll() { setTimeout(function() { $.ajax({ url: "server", success: function(data) { sales.setValue(data.value); }, dataType: "json", complete: poll }); }, 30000); })(); Let me know if that works for you. Then I will amend the article with your findings. If you come up with a more elegant solution, please do share it here as well.

Lars 10 Feb 12

@TVD: Yes, indeed, what worked for me (beautifully) was exactly the code with setTimeout that you quote, more or less. Thanks to you and this article the next version of Beetrieve™ will have no more "Update status" buttons. It might not keep the connection open, but it seems to work very well. Thanks again!

Amanjot Singh 13 Mar 12

Anyone can tell me how to keep open the ajax request on the apache server using php for long pooling

TVD 10 Apr 12

@Amanjot: If memory serves me right...Awhile back, I remember seeing a technique where one developer kept the request open indefinitely by not including the PHP close tag. Not entirely sure. However, might be worth a shot in your case. Good luck with your project.

Diego 13 Apr 12

Anyone tried with 1000 ms instead of 30000 ms? Looks like decreasing the timeout breaks the stack (js error: Maximum call stack size exceeded). Any hints on this? Thanks! Diego

TVD 13 Apr 12

@Diego: Yes. I've tried with a one second interval. It's just too short an interval for the browser and breaks the stack like you've seen. For tighter control on the update intervals, a server-side push state solution may be more appropriate for you. Something like SignalR (.NET), Socket.IO (Node.js), etc. Sometimes you can't update the server-side code to push state because you don't have control over the codebase. Or there could be a limitation in the server-side stack, limited development time, etc. Here, client-side Javascript Polling may not only be appropriate, but down-right necessary. In that case, you'll want to experiment with increasing the polling interval to something that works for your application scenario.

TVD 15 May 12

Thanks everyone for contributing your passion and knowledge! I truly believe The Future is JavaScript.

Comments are closed