One or another way a web developer at some time have to make some kind of real-time application. As web technologies move forward, so should user-experience get better and better, and one way is as You might guess – real-time applications, or in another words – applications that would work without refreshing web pages. There are many examples of using this kind of app, such as Facebook chat system, Twitter news updating, making interactive Google map with moving markers every 5 seconds. All of this would make no sense if the user would need to refresh his browser everytime he wants to see updates, if they even are on that time. It would be very insufficient. Here I will show you creating real time applications using server sent events and PHP.
What Is Server-Sent Events?
Server-Sent Events, or for short – SSE, is an API that let browsers get automatic updates from server via HTTP connection. It is a part of HTML5 and is standardized by W3C, so it is fully ok with using it as your real-time tehcnology. SSE is available through JavaScript, and to use it is super easy. You just need to create new EventSource object, specifying url of the file, where the updates will be generating, such as this example:
var source = new EventSource("ssefile.php");
After assigned the object to a variable, You can use several methods like onopen, onmessage, onerror and onclose.
onmessage
This method is used for listenning for new updates in a specified file. Everytime the a new update is available, onmessage event fires.
source.onmessage = function(e) { var element = document.getElementById("messageBox"); element.innerHTML = "message: " + e.data; }
onopen
Onopen event is fired when the SSE connection is established. So if You want to know when it’s fires, write this:
source.onopen = function(e) { console.log("The connection to your server has been opened"); }
onerror
Code this to know when the error occurs for debugging purposes:
source.onerror = function(e) { console.log("The server connection has been closed due to some errors"); }
onclose
Finally use onclose if you want to close connection at some point:
source.onclose();
Also events can be specified, if you have more than one update you want to show the user. For example:
source.addEventListener("message", function(e) { var messageBoard= document.getElementById("message_board"); var object= JSON.parse(e.data); newElement.innerHTML = "The message is: " + object.message; }, false);
Server Side Part
First of all, the server side script has to have a header with MIME type text/event-stream, which is created speciffically for server-sent events in order to work properly. After querying database or something like that, You need to echo it, following a pair of newlines, and then flush it to the client, like this:
$notification = $query_result; echo "data: {$notification}\n\n"; flush();
While I have seen many tutorials on using SSE, I didn’t like the way how some of them teaches it. For example this will work perfectly:
header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); $now = date('r'); echo "data: The time is : {$now}\n\n"; flush();
…unless You have more events you want to send. The thing is, after connection to the server side script is established in the browser, the connection will close after about 3 seconds. The callback of event sourse object will be error, because it could’nt hold the connection. Although as I said earlier it will work, however the best way is to hold the connectionwith the server as long as possible, not making unnecessary HTTP request every 3 seconds, which is very insufficient and intense resource usage. So the solution here is while loop:
while(true) { $now = date('r'); echo "data: The time is : {$now}\n\n"; ob_flush(); flush(); sleep(2); }
This block of code will hold the connection and send now time every 2 seconds, without reconnecting over and over again. As you might notice, sleep() function will let the loop to stop executing for 2 seconds for cooling down.
Last thing to mention is how to specify event:
echo "event: message\n"; echo "data: {$message}"; echo "\n\n";
It’s almost the same as the data should be specified, only event is followed by one pair line. You can send as many data with it’s specific event as you need, and then bind and listen to that event with JavaScript as was mentioned above.
In conclusion, I would say that server-sent events is the best technology for real-time apps written in PHP language, because it’s very easy to start using and not so much resource intensive consuming.
¿Tienes un ejemplo en marcha?
Si pongo dentro del bucle un lectura a la base de datos se me cae el servidor por numero de conexiones excedida.