3

as the title says, I found a rather strange behaviour in my application. It seems like the browsers pause the EventSource for about 4-5 seconds. The delay does not seem to come from my backend PHP script.

Detailed description

I am using the JavaScript EventSource to be able to show a download progress of one specific ZIP file (about 60MB of downloadable size). After that ZIP is downloaded, it gets extracted. Also, the user gets current informations on which shell command is executed at the moment so the user always knows what the backend is doing. To start the process, the user can click a button, which triggers the following js-function (basically just calls download_update.php and registers several event listeners for my EventSource object):

startUpdate() {
  this.updateRunning = true;
  const eventSource = new EventSource(`download_update.php?jwt=${this.authUser.jwt}`);
  eventSource.addEventListener('downloadProgress', (event) => {
    const socketPayload = JSON.parse(event.data);
    this.loadingPercent = socketPayload.percentage; // progress visible in loading circle
  });

  eventSource.addEventListener('updateError', (event) => {
    eventSource.close(); // make sure event source is closed to prevent restarting update process every few seconds
    this.updateRunning = false;
    this.loadingStatus = 'error';
    const errorPayload = JSON.parse(event.data);
    this.updateErrors.push(errorPayload.message);
  });

  eventSource.addEventListener('updateProgress', (event) => {
    this.updateProgressLogs.push(JSON.parse(event.data).log); // show specific update step
  });

  eventSource.addEventListener('updateFinished', () => {
    eventSource.close();
    this.updateRunning = false;
    this.loadingStatus = 'successful';
  });
},

I'm firing the Server Sent Events with the following PHP function inside the called download_update.php:

function fireEvent($name, $payload)
{
    $payload['time'] = date('H:i:s'); // pass server time to compare with browser time
    echo "retry: 1000\n"; // seems to have no impact on the delay
    echo "event: $name\n";
    echo 'data: ' . json_encode($payload);
    echo "\n\n";

    if (ob_get_contents()) {
        ob_flush(); // took these two function calls as a suggestion from another post on SO
        flush();
    }
}

This PHP function is triggered inside the callback function which I passed to the CURL request:

curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'downloadProgress'); // callback function 'downloadProgress' fires 'fireEvent' and passes the current downloadProgress in %

The script download_update.php is only called once, which is the desired bevaviour (I've checked that in my Chrome Network tab). But when I take a closer look at the results inside the Network tab of download_update.php, I get the following:

EventSource details in Network tab

As you can see in my screenshot, there is a sudden unexpected browser delay of about 6 seconds between the result I have highlighted and the previous one. The EventStream clearly says {"percentage":91,"time":"16:46:47"} (passed through backend PHP), but the browser is showing 16:46:52.319 as the time.

My page has HTTPS and is hosted on a local .test domain (localhost).

  • PHP Version 7.4.21
  • Webserver: nginx version 1.21.1 (used via Laravel Valet 2.18.10)
  • Tested on browsers: Chrome 100.0.4896.75, Firefox 99.0, Safari 15.4
  • Used hardware: MacBook Pro (16" 2021 M1), macOS Monterey Version 12.3.1

This behaviour occurs on all of the 3 browsers listed above, which leads me into thinking that the webserver nginx might be the issue here. I've found a pretty interesting question regarding EventSource and nginx: EventSource / Server-Sent Events through Nginx

The accepted answer suggests putting the following lines into one of the nginx config files (location section):

proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;

So I put those inside /usr/local/etc/nginx/valet/valet.conf and restarted my webserver several times, without success. Does anybody have any suggestions on how I can fix that delay?

Thank you very much in advance everyone.

MadCoder
  • 51
  • 4

0 Answers0