Reputation: 1511
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
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