0

My script is sending a GET request to a page (http://example.org/getlisting/) and the page, in turn, responds back with a JSON object. ({"success":true, "listingid":"123456"})

Here's an example snippet:

var listingAjax = new XMLHttpRequest();
listingAjax.addEventListener("load", listingCallback, false);

function listingCallback(event) {
    if (this.readyState == 4 && this.status == 200) {
       console.log(this.responseText);
    }
}

listingAjax.open("GET", "http://example.org/getlisting/", true);
listingAjax.send();

Simple enough. The script works perfectly too! The issue arises when I want to do this:

var listingAjax = new XMLHttpRequest();
listingAjax.addEventListener("load", listingCallback, false);

function listingCallback(event) {
    if (this.readyState == 4 && this.status == 200) {
       console.log(this.responseText);
    }
}

window.setInterval(function() {
    listingAjax.open("GET", "http://example.org/getlisting/", true);
    listingAjax.send();
}, 250);

What I imagine should happen is my script would create a steady flow of GET requests that get sent out to the server and then the server responds to each one. Then, my script will receive the server's responses and send them to the callback.

To be more exact, say I let this script run for 5 seconds and my script sent out 20 GET requests to the server in that time. I would expect that my callback (listingCallback) would be called 20 times as well.

The issue is, it isn't. It almost seems that, if I sent out two GET requests before I received a response from the server, then the response is ignored or discarded.

What am I doing wrong/misunderstanding from this?

NessDan
  • 1,137
  • 1
  • 16
  • 34
  • What browsers are you seeing this behaviour in? I'm not sure why it's happening, but I'm wondering if it's browser specific. – MJD Dec 31 '12 at 03:41
  • It's Google Chrome. I had planned on making it specific to it since I plan to convert this script to a NodeJS application in the future (next year some time ;) ) – NessDan Dec 31 '12 at 03:43

2 Answers2

2

Many browsers have a built in maximum number of open HTTP connections per server. You might be hitting that wall?

Here is an example from Mozilla but most browsers should have something like this built in: http://kb.mozillazine.org/Network.http.max-connections-per-server

An earlier question regarding Chrome: Increasing Google Chrome's max-connections-per-server limit to more than 6

If you have Windows, take a look at a tool like Fiddler - you might be able to see if all of the requests are actually being issued or if the browser is queueing/killing some of them.

Community
  • 1
  • 1
NYCdotNet
  • 4,500
  • 1
  • 25
  • 27
  • Yep. This. @NessDan, a GET request every quarter of a second is a lot (too much). If you need information real time, consider other solutions that use a persistent connection like long polling or web sockets. – vcsjones Dec 31 '12 at 03:50
  • Thanks for this, thankfully this wasn't the case (I didn't know if a GET request would count as a connection too.) – NessDan Dec 31 '12 at 04:00
1

You can't reuse the same XMLHttpRequest object opening a new connection while one is in progress, otherwise it will cause an abrupt abortion (tested in Chrome). Using a new XMLHttpRequest object for each call will solve that:

function listingCallback(event) {
    if (this.readyState == 4 && this.status == 200) {
       console.log(this.responseText);
    }
}

window.setInterval(function() {
    var listingAjax = new XMLHttpRequest();
    listingAjax.addEventListener("load", listingCallback, false);
    listingAjax.open("GET", "http://example.org/getlisting/", true);
    listingAjax.send();
}, 250);

This will work nicely queueing a new ajax request for each interval.

Fiddle

Note that too frequent calls may cause slowdown due to the maximum limit of concurrent ajax calls which is inherent to each browser.
Though, modern browsers have a pretty fair limit and very good parallelism, so as long as you're fetching just a small JSON object modern browsers should be able to keep up even when using a dial-up.

Last time I made an ajax polling script, I'd start a new request in the success handler of the previous request instead of using an interval, in order to minimize ajax calls. Not sure if this logic is applicable to your app though.

Fabrício Matté
  • 69,329
  • 26
  • 129
  • 166
  • 1
    IT WORKED! IT WORKED! IT WORKED! You don't know how long I've been messing with this thing! Thank you so much for your answer, I appreciate it! "Have I ever told you you're my hero?" :) – NessDan Dec 31 '12 at 03:58