I want to send regular updates from server to client. For that I used server-sent event. I'm pasting the codes below:
Client side
<script>
if(typeof(EventSource)!="undefined")
{
var source=new EventSource("demo_see.php");
source.onmessage=function(event)
{
document.getElementById("result").innerHTML=event.data + "<br>";
}
}
else
{
document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>
Server side
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$x=rand(0,1000);
echo "data:{$x}\n\n";
flush();
?>
The code works fine but it sends updates in every 3 seconds
. I want to send updates in milliseconds. I tried sleep(1)
after flush()
but it only increases the interval further by 1 sec. Does anyone have an Idea how I can accomplish this?
Also, can I send images using server-sent events?
As discussed in the comments above running a PHP script in an infinite loop with a sleep
or a usleep
is incorrect for two reasons
The right way to do things is to get your PHP script to respond with event stream data and then gracefully terminate as it would normally do. Provide a retry
value - in milliseconds - if you want to control when the browser tries again. Here is some sample code
function yourEventData(&$retry)
{
//do your own stuff here and return your event data.
//You might want to return a $retry value (milliseconds)
//so the browser knows when to try again (not the default 3000 ms)
}
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Access-Control-Allow-Origin: *');//optional
$data = yourEventData($retry);
echo "data:{$str}\n\nretry:{$retry}\n\n";
As an answer to the original question this is a bit late but nevertheless in the interests of completeness:
What you get when you poll the server in this way is just data. What you do with it afterwards is entirely up to you. If you want to treat those data as an image and update an image displayed in your web page you would simply do
document.getElementById("imageID").src = "data:image/png;base64," + Your event stream data;
So much for the principles. I have on occasion forgotten that retry
has to been in milliseconds and ended up returning, for example, retry:5\n\n
which, much to my surprise, still worked. However, I would hesitate to use SSE to update a browser side image at 100ms intervals. A more typical usage would be along the following lines
retry
value is setup so the browser knows when to look again for a result.data{"code":-1}\n\n
so browser side code can deal with the situation gracefully.There are other usage scenarios - updating stock quotes, news headlines etc. Updating images at 100ms intervals feels -a purely personal view - like a misuse of the technology.
It is now close to 5 years since I posted this answer and it still gets upvoted quite regularly. For the benefit of anyone still using it as a reference - in many ways SSE is, in my view, a rather outdated technology. With the advent of widespread support for WebSockets why bother doing SSE. Quite apart from anything else the cost of setting up and tearing down an HTTPS connection from the browser for each browser side retry is very high. The WSS protocol is far more efficient.
A spot of reading if you want to implement websockets
To my mind PHP is not a great language to handle websockets and Ratchet is far from easy to setup. The Nginx/NChan route is far easier.
The reason for this behavior (message every 3 seconds) is explained here:
The browser attempts to reconnect to the source roughly 3 seconds after each connection is closed
So one way to get message every 100 milliseconds is changing the reconnect time: (in the PHP)
echo "retry: 100\n\n";
This is not very elegant though, better approach would be endless loop in PHP that will sleep for 100 milliseconds on each iteration. There is good example here, just changing the sleep()
to usleep()
to support milliseconds:
while (1) {
$x=rand(0,1000);
echo "data:{$x}\n\n";
flush();
usleep(100000); //1000000 = 1 seconds
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With