server sent events while loop takes so much time for page load, when page is refreshed or F5 is pressed

1.4k views Asked by At

I am using server sent events to query database for new records and display the events to the user

Here is my code

javascript

window.onload = function setDataSource() {

if (!!window.EventSource) {
var source = new EventSource("polling.php");

source.addEventListener("message", function(e) {
  console.log(e.data);
}, false);

source.addEventListener("open", function(e) {
  console.log("OPENED");
}, false);

source.addEventListener("error", function(e) {
  console.log(e);
  if (e.readyState == EventSource.CLOSED) {
    console.log("CLOSED");
  }
}, false); } else {}}

PHP

  <?php
  header("Content-Type: text/event-stream\n\n");
  include_once dirname(__FILE__) . '/db.php';
  session_start();

   while (1) {
   $response = getnewmessages();
   echo 'data: Message '. json_encode1($response)."\n\n";
   ob_flush();
   flush();
   sleep(5);

   }

 function getnewmessages ()
{
// query database and get new records.
 }

It works fine and gets the new records for every 5 seconds. But the problem here is when I refresh the page manually,it takes so much time for page load.

When the page is loading, I can figure out that while loop still executes (at least thrice) and pauses the page. After so much time page starts loading normally. So my doubt is the while loop is pausing the execution

Can you please suggest me how to overcome this situation ? or How can I replace while loop?

1

There are 1 answers

1
Marc B On BEST ANSWER

Two problems: 1. PHP file-based sessions lock the session file while it's in use 2. PHP cannot detect that the client has disconnected until AFTER it tries to do some output

So, worst case, your refresh script runs, dumps out any updates, and then sleeps for 5 seconds. If the client refreshes at the exact same moment, it will now take 5 for another loop iteration to occur, and some output to be produced, allowing PHP to realize that the connection's closed.

Quick fix: session_write_close() to release the lock on the session file, allowing parallel requests to occur.

Long term fix: use something better than a polling loop to check for messages, e.g. websockets.