hedgehog90
hedgehog90

Reputation: 1511

Never-ending ajax request, good idea / bad idea?

For the backend of my site, visible only to a few people, I have a system whereby I communicate with a php via ajax like so:

function ajax(url, opts) {
    var progress = false, all_responses = [], previousResponseLength = "";
    var ajaxOptions = {
        dataType: "json",
        type: "POST",
        url: url,
        xhrFields: {
            onprogress: function(e) {
                if (!e.target.responseText.endsWith("\n")) return;
                var response = e.target.responseText.substring(previousResponseLength).trim();
                previousResponseLength = e.target.responseText.length;
                var responses = response.split(/[\r\n]+/g);
                var last_response;
                for (var k in responses) {
                    if (responses[k] === "---START PROGRESS---") {
                        progress = true;
                        if (opts.onProgressInit) opts.onProgressInit();
                    } else if (responses[k] === "---END PROGRESS---") progress = false;
                    else all_responses.push(last_response = responses[k]);
                }
                if (progress && last_response !== undefined) opts.onProgress(JSON.parse(all_responses[all_responses.length-1]));
            }
        },
        dataFilter: function(data){
            return all_responses[all_responses.length-1];
        }
    }

    $.extend(ajaxOptions, {
        onProgress: function(data){
            console.log(data);
        }
    });

    return $.ajax(ajaxOptions);
}

And an example of a never-ending php script (until the user closes the connection):

const AJAX_START_PROGRESS = "---START PROGRESS---";
const AJAX_END_PROGRESS = "---END PROGRESS---";

session_write_close(); //fixes problem of stalling entire php environment while script runs
set_time_limit(0); //allows to the script to run indefinitely
output(AJAX_START_PROGRESS);
while(true) {
    output(json_encode(["asdasd" => "asasdas"]));
    sleep(1);
}

function output($msg) {
    echo preg_replace("`[\r\n]+`", "", $msg).PHP_EOL;
    ob_flush(); flush();
}

This allows me through 1 ajax request to 'poll' (am I using that term correctly?) So if I want to execute a very long php script I can now check its progress, and the last response is delivered via jqhxr.done(callback).

Or, as in the example php script, I can open a connection and leave it open. Using sleep(1); It issues an update to the $.ajax object every 1 second. Every response has to be json encoded, and if the response is 1 very long json that comes over multiple 'onprogress' calls, it waits until the end of the message (if responseText.endsWith("\n")) we're ready!)

My remote shared server didn't allow websockets so I made this. If the user closes the connection, so does the php script. It's only got to work for a few admins with special privileges, and I don't need to worry about old browsers.

Can anyone see anything wrong with this script? Through googling I haven't found anybody else with this kind of method, so I expect something is wrong with it. Extensive testing tells me it works just fine.

Upvotes: 2

Views: 199

Answers (1)

arturkin
arturkin

Reputation: 957

You invented long polling request, actually it's wide used as fallback to websockets, so nothing wrong with it. About your code it's hard to say without testing, but when using such methods as long-polling, you need to double check memory leaks on browser side and on server side.

Upvotes: 1

Related Questions