9

Hello I have a javascript code that listens to a PHP code via Server-Sent Events, it is working well the response is sent from the server trough a loop and when the loop ends the Server-Sent Events stops however a few seconds after the script is again listening. how can I end the Server-Sent Events when the loop from the server side ends too? Thanks.

JS :

var sse=new EventSource("data.php");
            sse.onmessage=function(event){
                document.getElementById("map").innerHTML+=event.data;              
            };

PHP:

<?php
header('Content-Type: text/event-stream'); //indicates that server is aware of server sent events
header('Cache-Control: no-cache');//disable caching of response

$coordinates = [  
   [  
      "20:11",
      33.5731235,
      -7.6433045
   ],
   [  
      "20:11",
      33.5731054,
      -7.6432876
   ],
   [  
      "20:11",
      33.5731644,
      -7.6433304
   ]
];

foreach($coordinates as $c){  
  echo "data: ".json_encode($c)."\n\n";
  ob_get_flush();
  flush();
  sleep(1);
}
oussama kamal
  • 1,027
  • 2
  • 20
  • 44

2 Answers2

4

You could use a boolean variable isOpenOnce = false in your javascript and then in your sse.onopen set isOpen to true the first time. In the beginning check the flag and close connection if true. This way no need of server side changes.

var isOpenOnce = false;
sse.onopen = function() {
 if(isOpenOnce) {
  sse.close();
 }else {
  console.log("Connection to server opened.");
  isOpenOnce = true;
 }
}
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Vijesh
  • 76
  • 3
2

Hi I've added extra to (hopefully fix this) You have to pass from the server a message to close the connection. Otherwise when the execution finishes the browser will start with a new connection

air code

JS :

var sse=new EventSource("data.php");
sse.onmessage=function(event){
    if ('END-OF-STREAM' == event.data) {
        sse.close(); // stop retry
    }
    document.getElementById("map").innerHTML+=event.data;
};

PHP:

<?php
header('Content-Type: text/event-stream'); //indicates that server is aware of server sent events
header('Cache-Control: no-cache');//disable caching of response

$coordinates = [
   [
      "20:11",
      33.5731235,
      -7.6433045
   ],
   [
      "20:11",
      33.5731054,
      -7.6432876
   ],
   [
      "20:11",
      33.5731644,
      -7.6433304
   ]
];

foreach($coordinates as $c){
    echo "data: ".json_encode($c)."\n\n";
    ob_get_flush();
    flush();
    sleep( rand ( 1 , 3 ) );
}
echo "data: END-OF-STREAM\n\n"; // Give browser a signal to stop re-opening connection
ob_get_flush();
flush();
sleep(1); // give browser enough time to close connection
John Griffiths
  • 3,263
  • 4
  • 21
  • 19
  • 3
    No need to send "data: END-IF-STREAM." Just send an event instead, like "event: close" and listen to that with sse.addEventListener('close', fucntion(){ sse.close(); }); – Simon Jul 07 '21 at 09:06