Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EventSource: always getting error

To get start with EventSource API I wrote the most scholastic example. The problem is that I'm always getting error and I can't find any useful information about it. When I load home.html, the JS script stops at source.onerror; I print it into the console but analyzing the object I can't find any error type or message so I have no idea of what it's wrong. Is there an error in the code? Could be an error related to the server?


home.html

<body>
  <div id="result"></div>
  <script src="sse.js"></script>
</body>

sse.js

function isSseEnabled() {
    return (typeof EventSource !== "undefined");
}

if (isSseEnabled()) {
    var source = new EventSource('source.php');
    source.onerror = function(e) {
        console.log(e);
        source.close();
    };
    source.onmessage = function (e) {
        console.log(e.data);
        document.getElementById('result').innerHTML += e.data.concat('<br>');
    }
} else {
    throw 'SSE not enabled';
}

source.php

<?php
header('Content-Type: text/event-stream');
header('Cache-control: no-cache');

$time = date('r');
echo "Time: $time";
flush();
like image 753
Brigo Avatar asked Nov 18 '22 17:11

Brigo


1 Answers

(TLDR: you are not using the SSE protocol - see second half of this answer.)

The first thing you need to do is get a proper error message, or at least look at your script is producing. I'd suggest using curl to test your script. From the commandline:

curl http://127.0.0.1/source.php

(I've assumed both your html and source.php are on your local machine, and not using https; adjust the above if not. Also adjust to add the path to source.php.)

If that works, or you don't have curl available, look at the developer tools in your browser. Look to see what is happening with the connection to source.php, what is being sent, and what is being received.

However, there are definitely a couple of ways to improve the PHP script. First prefix the message with "data:" and add the couple of LFs after each message; this is required by the SSE protocol.

Second, use an infinite loop with a sleep in it (there is never any point having an SSE script that returns one thing and closes - you might as well just use AJAX, in that case). So it would look like this:

<?php
header('Content-Type: text/event-stream');
header('Cache-control: no-cache');

while(true){
    $time = date('r');
    echo "data:Time: $time\n\n";
    @ob_flush();flush();
    sleep(1);
    }
like image 127
Darren Cook Avatar answered Dec 24 '22 01:12

Darren Cook