1

I want to write a realtime server log viewer and just learned about SSE. I'm confused as to how to use it properly though. I'm running a Linux server with php 5.4. I have this code right now:

HTML + JS:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <ul id='el'></ul>
    <script type="text/javascript">
        var eSource = new EventSource("ssedemo.php");
        eSource.onmessage = function(event) {
            var e = document.createElement("li");
            e.innerHTML = event.data;
            document.getElementById('el').appendChild(e);
        };
    </script>
</body>
</html>

PHP:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\n";
ob_flush();
flush();
?>

This works, but it drops the connection after each update and the client re-establishes it every 3 seconds. I would like it to update faster. From the documentation and tutorials online, it seems that the proper way to use SSE is to wrap the server code in a loop to maintain the connection, and use sleep to control the update time:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(true) {
    $time = date('r');
    echo "data: The server time is: {$time}\n\n";
    ob_flush();
    flush();
    sleep(1);
};
?>

The problem is that this doesn't work. Whenever I introduce a loop, onmessage is never called on the client side. I have tried numerous examples without altering any code (https://github.com/html5rocks/www.html5rocks.com/tree/master/content/tutorials/eventsource/basics/static/demo), (https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events), etc, but none of them work unless I remove the loop from the php.

Why can't I maintain the connection? Did something change in php 5.4 that prevents this from working?

Cbas
  • 6,003
  • 11
  • 56
  • 87
  • Which browser are you using? And is this a localhost server, or a remote server? – Darren Cook Dec 15 '14 at 10:37
  • remote server. I tried with Chrome, Firefox, and IE, same behavior in all cases – Cbas Dec 15 '14 at 18:30
  • 1
    As a minor aside, I assume you got no output at all with your first example (no-while-loop) with IE (as it doesn't support SSE)? – Darren Cook Dec 15 '14 at 21:35
  • @DarrenCook Correct, thanks for clarifying - I tested the second example in all browsers and it didn't work in any of them. I just tested the first example across browsers and it worked in all except IE – Cbas Dec 22 '14 at 20:35

1 Answers1

1

To answer your last question first, there was no change in php 5.4 that would stop this working.

Everything looks correct to me. Instead of onmessage I have always used it like this:

eSource.addEventHandler('message', function(event) {
  var e = document.createElement("li");
  e.innerHTML = event.data;
  document.getElementById('el').appendChild(e);
}, false);

But I think either way is fine. (Confirmed by you saying it works when there is no while loop, and only one data packet is sent.)

So, all I can do is offer a couple of troubleshooting ideas:

Can you use Firebug, or the chrome developer console, to see what the connection is doing?

Do you see it being closed immediately (which would imply some syntax error, or other crash in your PHP script), or does it stay open forever but not receiving any data (which would imply there is server-side caching, or an intermediate proxy server caching), or does it stay open forever, and receiving data (which would suggest there is something wrong with your JavaScript).

Also check the JS console for any warnings, and check the server-side PHP error log for warnings.

Darren Cook
  • 27,837
  • 13
  • 117
  • 217
  • In the chrome console, there are no JS warnings/errors, and the connection stays open without receiving data - it shows 'Pending', then cancels after about 2 minutes. I enabled debug logs on my server, and a new log file was created, but no errors showed up after refreshing the demo page a few times – Cbas Dec 22 '14 at 20:47
  • @Cbas Interesting; it definitely sounds like a server-side issue (or an intermediate firewall or load balancer). It might be worth adding to your question: which linux distro, and if it is a shared or dedicated server, and anything you know about the network topology. I'd be interested/surprised if you could reproduce the problem with a fresh EC2 (or similar) instance. – Darren Cook Dec 22 '14 at 21:31
  • I think so too. I am using a shared hosting account and when I called my service provider, they said the OS was an old, custom built Linux distro that is no longer supported by their IT department - probably the root of the problem.. I am going to switch to a different shared hosting account on a newer Linux distro and post back about the results. – Cbas Dec 29 '14 at 03:58