I want to ask this question with a simply example. (I will write down at the end of the post).
I have read this: server sent events not updating until script is finished
But I don't know how to solve it.
With the solution of its answer (https://mcmap.net/q/1917465/-server-sent-events-not-updating-until-script-is-finished) works perfect, so may be it is a problem of cache in my production server (share web hosting).
I recieve all the EventStream at the end, all in a row at the same time.
I have already checked all combinations of:
header('Cache-Control: no-cache, no-store, must-revalidate, private, max-age=0');
header('Pragma: no-cache');
header('Expires: 0');
But no luck
Any one knows how to solve this without "str_pad($message, 800000)" ?
Any clue to compare my localhost configuration of the server and the shared hostweb server?
Thanks,
NOTE 1: php version 8 in both enviroments. I have checked that I work with apached as developement enviroment and CGI/FastCGI in my shared webserver. Is it related? I have found this: Event Source -> Server returns event stream in bulk rather then returning in chunk
NOTE 2: Output buffering is the same in both servers: output_buffering 4096
This is a simple example that doesnt work in my hosting:
test.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<br />
<input type="button" onclick="startTask();" value="Start Long Task" />
<input type="button" onclick="stopTask();" value="Stop Task" />
<br />
<br />
<p>Results</p>
<br />
<div id="results" style="border:1px solid #000; padding:10px; width:300px; height:250px; overflow:auto; background:#eee;"></div>
<br />
<progress id='progressor' value="0" max='100' ></progress>
<span id="percentage" style="text-align:right; display:block; margin-top:5px;">0</span>
</body>
</html>
<script>
var es;
function startTask() {
if (!!window.EventSource) {
es = new EventSource('long_process.php');
//a message is received
es.addEventListener('message', function(e) {
var result = JSON.parse( e.data );
addLog(result.message);
if(e.lastEventId == 'CLOSE') {
addLog('Received CLOSE closing');
es.close();
var pBar = document.getElementById('progressor');
pBar.value = pBar.max; //max out the progress bar
}
else {
var pBar = document.getElementById('progressor');
pBar.value = result.progress;
var perc = document.getElementById('percentage');
perc.innerHTML = result.progress + "%";
perc.style.width = (Math.floor(pBar.clientWidth * (result.progress/100)) + 15) + 'px';
}
});
es.addEventListener('error', function(e) {
addLog('Error occurred');
es.close();
});
}
}
function stopTask() {
es.close();
addLog('Interrupted');
}
function addLog(message) {
var r = document.getElementById('results');
r.innerHTML += message + '<br>';
r.scrollTop = r.scrollHeight;
}
</script>
long_process.php
<?php
header('Content-Type: text/event-stream');
// recommended to prevent caching of event data.
header('Cache-Control: no-cache');
function send_message($id, $message, $progress) {
$d = array('message' => $message , 'progress' => $progress);
echo "id: $id" . PHP_EOL;
echo "data: " . json_encode($d) . PHP_EOL;
echo PHP_EOL;
//push the data out by all force possible
ob_flush();
flush();
}
//LONG RUNNING TASK
for($i = 1; $i <= 10; $i++) {
send_message($i, 'on iteration ' . $i . ' of 10' , $i*10);
sleep(1);
}
send_message('CLOSE', 'Process complete', 100);
?>
UPDATE About @Tigger answer: I have used this code, but no luck. Again I recieve all in a row at the end of the script (10seconds), not a message every 1 second. (I have also checked "\n" and PHP_EOL).
function send_message($id, $message, $progress) {
$d = array('message' => $message , 'progress' => $progress);
echo "id: $id" . "\n";
echo "data: " . json_encode($d) . "\n";
echo "\n";
//push the data out by all force possible
while(ob_get_level() > 0) {
ob_end_flush();
}
flush();
}
UPDATE About second @Tigger answer I have used MDN sample on GitHub and no luck. XAMPP works, my production webserver ... doesn't.
UPDATE About hosting provider As I have not found a solution, I have contacted with my shared web hosting, and here is their answer:
(translate with google):
Hello, After analyzing the case, as we have been able to verify, the use of SSE on a platform like ours with an nginx proxy ahead of apache, would require certain customizations in the nginx configuration of the hosting, which makes it incompatible with the service of shared hosting. You need a service that is more customizable such as a vps, or a virtual private server or similar. Greetings,
As I can't change nginx configuration, is it any other configuration/command in my php files or javascript that will help me?
fastCGI
, notCGI
– Ashleeashleigh