Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

long-poll jQuery.ajax() fails to callback after phone sleeps?

My web app uses the 'long poll' method to keep up to date with the latest data from my server. The server only responds when it has new data, which can be many minutes apart. (It is a heating control system where you only see updates when room temperatures changes or somebody changes the settings).

var version = "0";
function updater() {
    $.ajax({
        type: "POST",
        url: "/listen",
        data: version,
        success: function (data) {
            version = handleUpdates(data);
            updater();
        },
        error: function () {
            setTimeout(updater, 1000);
        }
    });
}

It works fine on desktop browsers and on phones except in one case. I have found that on android phones with Chrome something odd happens after the phone has gone to sleep for more then about 10 minutes. The post request seems to be dropped, which I guess is reasonable since the phone is asleep. In the Chrome debugger's Network tab, the Status Text of the POST request says (canceled).

The problem is when I wake the phone up while the request is cancelled, neither the success() or error() function is called, and my web app never gets updated. $.ajax() has broken its promise to call me back.

The problem only happens on some devices. I have been able to do a few ad-hoc tests by borrowing devices off friends. So far I have only seen the problem on android phones. But not is the phone is connected to a charger. I have not seen it on any tablets, on apple devices or windows PCs.

I have tried adding a timeout to the ajax settings:

     timeout: 120 * 1000,

This helps because the error() function is eventually called up to 2 minutes after the wake up. But I'd like the user to see updates within 1 or 2 seconds. I don't want to make the timeout so short because it would create unnecessary server traffic.

I have also tried detecting whether device is asleep by looking for lateness in a one second setInterval as described in Can any desktop browsers detect when the computer resumes from sleep?. When I detect the wake up, I abort() the post and start another. This helps in most cases. But it turns out to be unreliable. Sometimes time events seem to keep ticking normally during sleep and the post request gets cancelled anyway. And it it does not feel like a reliable fix.

I am using latest version of jQuery: (2.1.2) and Chrome (47).

like image 929
James Avatar asked Dec 17 '15 17:12

James


People also ask

What are the deprecated callbacks in jQuery Ajax?

Docs for jquery Ajax function W3 specs regarding http/1.1 status codes Deprecation Notice: The jqXHR.success (), jqXHR.error (), and jqXHR.complete () callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done (), jqXHR.fail (), and jqXHR.always () instead.

What is a jQuery Ajax fail?

The jQuery ajax fail is an ajax event which is only called if the request fails. The AJAX fail is a global event that triggered on the document to call handler function, which may be listening. The ajax fail can be performed with the help of the ajaxError () function. The jQuery ajaxError () function is a built-in function in jQuery.

What happened to success error and complete callbacks in jQuery?

Update: As of JQuery 3.0, the success, error and complete callbacks have all been removed. As a result, you will have to use the done, fail and always callbacks instead. An example of done and fail being used:

Why is my Ajax request not working?

Check if the Request contains typos or is missing mandatory fields. Also keep in mind that the Ports have to match when executing an AJAX call. 1) Server is setup to handle PUT requests 2) commenting out data was intentional. First time, I tried with data (no comments). It was giving the same problem.


1 Answers

I've had problems in the past with JavaScript calls getting suspended when the phone goes to sleep. The solution I ended up with was to use window.setInterval() which seems to suspend, but come back to life when the phone is woken up.

So I would recommend setting an interval which cancels the call every so often and reinitiates it. This might help it survive through a phone sleep.

Something roughly like:

var myCall = $.ajax({...});

Window.setInterval (refreshCall(), 10000);

function refreshCall (){
    myCall.abort ();
    myCall = $.ajax({...});
}
like image 76
spozun Avatar answered Nov 15 '22 23:11

spozun