HTML5 and Server-Sent Events

Real-Time Web

Related articles: Bringing realtime to your web applications and WebSockets vs Server-Sent Events vs Long-polling

Besides, already noted bidirectional communication channel, known as WebSocket, HTML5 propositions include also comet communication pattern by defining Server-Sent Events (SSE). WebSocket widely discussed by now, tons of server implementations are available and you can play already with fluent browser implementation under Chrome. However the second server-push technology of HTML5 yet stays in shadow.

We are used to consider the HTTP protocol as request-response model, which means that the client sends a HTTP request and waits until the HTTP response is received. So, normally the server cannot communicate to client unless it’s requested. Even to have such a trivial thing as user online status we are obliged to go with workarounds. You know, it’s called COMET and whatever approach you choose it’s still a hack. HTML5 is designed to change it. It provides a native way to handle server-sent events. HTML 5 defines an API for opening an HTTP connection for receiving push notifications from a server. Just check it out how easy to use the interface is:

var source = new EventSource('updates.php');
source.onmessage = function (event) {
  alert(event.data);
};

The server-side scripts keeps sending messages in following form (text/event-stream MIME type):

data: TROLOLOLOLOLOLOLOLOLOLO
data: Lorem ipsum dolor sit amet
data: consectetur adipiscing elit.
data: Vestibulum rutrum nisi in diam dapibus eget tempor mauris sollicitudin

Moreover, you don’t need to apply a loop-cycle in the event source script. That will seem as repeat of pushing messages to the client automatically.

<?php
header("Content-Type: text/event-stream\n\n");
echo 'data: ' . time() . "\n";
?>
Developer console of Chrome 6 displays sever controller is being requested

How does it work? The client opens an event stream by creating an EventSource, which takes an event source URL as parameter. The onmessage event handler will be called each time new data of event source comes. You see, having AJAX, we can asynchronously communicate from the client to the server and, now using SSE we can do it in opposite direction from the server to the client, again asynchronously.

WebWorkers is other nice technology of HTML5. This one allows running scripts in the background independently. So you can handle the per-server connection limitation of browsers by using a shared WebWorker instead of multiply declaration of EventSource from the same domain.

Is it real? In fact SSE is available in Safari 5.0, Google Chrome 6 development version and in Opera 9. The last implementation differs from that I mentioned above. You have to declare an element in HTML DOM to which the event listener will be attached.

<event-source src="events.php" ></event>

Besides, the server sends messages addressed to different listeners:

document.getElementsByTagName("event-source")[0]
        .addEventListener("server-time", function (event) {
        alert(event.data);
    }, false);

Server-side controller can look like that

<?php
header("Content-Type: application/x-dom-event-stream");
    echo "Event: server-time\n";
    echo "data: " . time() . "\n";
    flush();
?>

Here I made an example by which you can test your browser against SSE. It doesn’t use developer console, so you will see upcoming server messages right on the page.