2
    <!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>SSE</title>
<script type="text/javascript">
    if (!!window.EventSource) {
        var source = new EventSource("sse.php");
    } else {
        alert("Your browser does not support Server-sent events! Please upgrade it!");
    }

    source.addEventListener("message", function(e) {
        console.log(e.data);
        if(e.data){
            x = document.getElementById("timer");
            x.innerHTML=e.data;
            console.log(e.data);
        }else{
            console.log(e.data);
            e.close();
        }
    }, false);

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

    source.addEventListener("error", function(e) {
        console.log("Error - connection was lost."+e);
    }, false);

</script>
</head>
<body>
<div id="timer"></div>
</body>
</html>

My Server Side Code

<?php
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");
$lastId = 0;
while (true) {
    $data =10; 
    if ($data) {
        sendMessage($lastId, $data);
        $lastId++;
        $data--;
    }else{
        exit;
    }
}

function sendMessage($id, $data) {
    //echo "id: $id\n";
    echo "$data\n\n";
    ob_flush();
    flush();
}
?>

What is wrong with my code? Please let me know.

Gibbs
  • 21,904
  • 13
  • 74
  • 138
  • Does this answer your question? [While loops for server-sent events are causing page to freeze](https://stackoverflow.com/questions/29480791/while-loops-for-server-sent-events-are-causing-page-to-freeze) – pato Dec 03 '21 at 19:26

1 Answers1

0

SERVER-SIDE: normally this kind of demo has a sleep between sending each message. What it will do, as it stands, is send 10 packets out in the space of 10ms (or something).

So, the client will get them all at almost the same time, and you will see just the "1" in your timer <div>.

CLIENT-SIDE: It looks okay. It'd be useful to have seen what is being logged to console though. (Probably 10, 10, 9, 9, .., 1, 1, 10, 10, 9, 9, ... repeating forever - see next bit.)

BOTH: I think what will happen when you exit is that the socket will close, the browser will detect that and reconnect. Giving you the same sequence again!


Putting that altogether, change your server-side code main loop to something like:

while (true) {
    $data =10; 
    if ($data) {
        sendMessage($lastId, $data);
        $lastId++;
        $data--;
    }else{
        sendMessage($lastId, "0");
        sleep(1); //Give client time to deal with it.
        break;
    }
sleep(1);  //1 sec between messages
}

I.e. send an explicit "0" to tell the client to disconnect.

Then on the client-side, look out for that explicit close code. (Actually I'd go with "END" or something, as "0" is too easy to evaluated as boolean false!)

source.addEventListener("message", function(e) {
    console.log(e.data);
    if(e.data==="0")e.close();
    else if(e.data){
        x = document.getElementById("timer");
        x.innerHTML=e.data;
        }
    //else do nothing
}, false);
Darren Cook
  • 27,837
  • 13
  • 117
  • 217