2
votes

I have implemented a server sent events with eventsource on my web application. Basically in javascript my code look like :

    var myEventSource;
    if (typeof(EventSource) !== "undefined" && !myJsIssetFunction(viridem.serverSideEvent.config.reindexProcessingEvent)) {
        myEventSource = new EventSource('/my/url/path.php?event=myevent');
        EventSource.onmessage = function(e) {
          [...] //Dealing with e.data that i received ...
        }
    }

on the PHP side I have something Like this :

<?php
  header('Content-Type: text/event-stream');
  header('Cache-Control: no-cache');
  header("Access-Control-Allow-Origin: *");

  //this or set_the_limit don't work but whatever I can deal without it
  ini_set('max_execution_time', 300);
  //ignore_user_abort(true); tried with true and false

  bool $mustQuit = false;

  while (!$mustQuit && connection_status() == CONNECTION_NORMAL) {
     if(connection_aborted()){
      exit();
     }
     [...] //doing some checkup

    if ($hasChange) {
      //Output stuffs
      echo 'data:';
      echo json_encode($result);
      echo "\n\n";
      ob_flush();
      flush();
      sleep(5);
    }

  }

from the answer found at : PHP Event Source keeps executing , the "text/event-stream" headers should make the connection close automatically but it doesn't in my case ..

I did add an eventsource.close in the window.onbeforeunload event but it didn't close the event.

window.onbeforeunload =  function() {
    myEventSource.close();
    myEventSource = null;
};

If I look the network section of my browser I can see the Headers are (after adding maximum loop of 30) : Content-Type: text/event-stream;charset=UTF-8

Response Headers:

Access-Control-Allow-Origin: *

Cache-Control: no-cache

Connection: Keep-Alive

Content-Type: text/event-stream;charset=UTF-8

Server: Apache/2.4.18 (Ubuntu)

Date: Thu, 26 Apr 2018 20:29:46 GMT

Expires: Thu, 19 Nov 1981 08:52:00 GMT

Request Headers:

Connection: keep-alive

Accept: text/event-stream

Cache-Control: no-cache

Note : I confirm that the script is still running with logs and by checking apache2 process with bash (ps -ax | grep -c apache2) that are always incrementing.

1
Just do while (true) { if (connection_aborted()) { exit(); I've used this for a while and kills process fine. For example: stackoverflow.com/a/49081040/661872Lawrence Cherone
connection_aborted() is always returning int(0) :/Jordan Daigle
Not sure how your testing that but you also need ignore_user_abort(true); which you have it off.Lawrence Cherone
And you shouldnt be using max_execution_timeLawrence Cherone
The idea is that it does run continuously, and only exits once a client disconnects.. you could put inside the loop a check which safeguards from overunning like github.com/lcherone/sse-chat-example/blob/master/sse.php#L89 but it wouldn't be needed in most cases.. as connection_aborted works fine.Lawrence Cherone

1 Answers

2
votes

Thanks to @LawrenceCherone help, I did find out that you need to "output data" for connection_aborted to work...

In my case I was outputing data only when I needed to ...

by adding

   if ($hasChange) {
      //Output stuffs
      echo 'data:';
      echo json_encode($result);
      echo "\n\n";
      ob_flush();
      flush();
      sleep(5);

    } else {
       echo 'data:';
       echo "\n\n";
       ob_flush();
       flush();
       if(connection_aborted()){
         exit();
       }
       sleep(5);
    }

connection_aborted started working.