Search code examples
javascriptphpfirefoxserver-sent-events

How to get Firefox respect SSE retry time in short intervals?


I want server-sent event updates every 100 ms, and this works for Chrome and Edge, but not for Firefox, unless I use some other method. But perhaps this can be overcome in Firefox too?

Normally the method would be (see the code) sse100.html + sse100.php. And Firefox really respects the "retry" field, however only to about >500ms. To get it working <500ms, I could use something like setInterval() and it really works, but this means new EventSource has to be created every time, which kind of makes using SSE obsolete (right?). Am I doing something wrong? Is this sse100.html + sse100.php or some deviation of that working for you in Firefox? Or is this perhaps something that is decided for Firefox, to prevent ? Maybe it could get faster if you would get some action or permission from the user?

(This is for a game where you could also be a passive spectator and watch how other players' positions are changing, and it's like one move per 200ms, so SSE seems optimal for that, and game ticks would be implemented as SSE.)

sse100.html:

<script>
var source = new EventSource("sse100.php");
source.addEventListener('message', (event) => { 
document.getElementById("result").innerHTML += event.data + "<br>";
});
</script>
<p id="result"></p>

sseinterval.html:

<script>
setInterval(() => {

var source = new EventSource("sseinterval.php");
source.addEventListener('message', (event) => { 
document.getElementById("result").innerHTML += event.data + "<br>";
});

}, 100);
</script>
<p id="result"></p>

sse100.php:

<?php
header("Content-Type: text/event-stream");
$curDate = date_create()->format("Y-m-d H:i:s.v");
echo "event: message\n";
echo "data: " . $curDate . " \n\n";

echo "retry: 100\n\n";

flush();

sseinterval.php:

<?php
header("Content-Type: text/event-stream");
$curDate = date_create()->format("Y-m-d H:i:s.v");
echo "event: message\n";
echo "data: " . $curDate . " \n\n";
flush();

Solution

  • I finally got it working for Firefox too. I had tried while(1){}, sleep and flushes many times, but it simply didn't work. This works, and adding "retry:" doesn't really affect here. Of course it can be important to stop the connection too, but this is just a minimal example. This is 100ms interval, but in my system, very short intervals seem to work fine too.

    <?php
    header("Content-Type: text/event-stream");
    
    while (1) {
    
    echo "data: This is a fast message \n\n";
    
    ob_end_flush();
    flush();
    
    usleep(100000);
    }
    ?>