Introduction to Server-Sent Events

While the web development world is abuzz over the “exciting future” of Web Sockets, there’s another spec along the same lines that has me far more excited: Server-Sent Events. This spec is based on a feature that was first called Server-Sent DOM Events and implemented in Opera 9. The idea is pretty simple: a web page can subscribe to a stream of events generated by the server. Whenever an event occurs on the server, a notification is sent to the client and a JavaScript event is generated.

Differences from Web Socket

The biggest difference between Web Sockets and Server-Sent Events is that the former is bidirectional while the latter is not. Server-Sent Events, as the name implies, are sent from the server to the browser only. If you wish to send data to the server, you’ll have to do so through another mechanism, such as XMLHttpRequest.

The second fairly large difference is that Server-Sent Events are sent over plain old HTTP without any modification. This is good news for implementers as there won’t be changes on the server aside from ensuring that high-duration requests don’t crash your server. Using HTTP ensures that Server-Sent Events won’t be hampered in its progress by the same protocol angst that is still swirling around Web Sockets.

The API

The JavaScript API for Server-Sent Events is very similar to that of Web Sockets. To subscribe to a new event stream, you start by creating a new EventSource object and pass in the entrypoint:

var source = new EventSource("myevents.php");

Note that the referenced URL must be on the same origin (scheme, domain, and port) as the page in which the object is created. The EventSource instance has a readyState property that is set to 0 to indicate it’s connecting to the server, 1 to indicate an open connection, and 2 to indicate a closed connection.

There are also three events: open, which is fired when the connection is established, message, which is fired when a new event is received from the server, and error, which is fired when no connection can be made. In general usage, the onmessage event handler is likely the one you’ll use the most:

source.onmessage = function(event){
    var data = event.data;
};

Information sent back from the server is returned via event.data as a string.

By default, the EventSource object will attempt to keep the connection alive with the server. You can force the object to disconnect immediately and stop attempting to reconnect by calling the close() method:

source.close();

The event stream

The server events are sent along a long-lasting HTTP request with a MIME type of text/event-stream. The format of the response is plain text and, in its simplest form, is made up of the prefix data: followed by text, such as:

data: foo

data: bar

data: foo
data: bar

The first part of this stream fires a message event with event.data set to “foo”; the second part fires a message event with event.data set to “bar”; the third fires a message event with event.data set to “foo\nbar” (note the newline character in between). When there are two or more consecutive lines beginning with data:, it is interpreted as a multiline piece of data and the values are concatenated together with a newline character. The message event is never fired until a blank line is encountered after a line containing data:, so be certain to include that extra newline when generating the event stream on the server.

You can also associate an ID with a particular event by including an id: line before or after the data: line(s):

data: foo
id: 1

By setting an ID, the EventSource object keeps track of the last event fired. If the connection is dropped, a special HTTP header called Last-Event-ID is sent along with the request so that the server can determine which event is appropriate to fire next.

Wrap up

Server-Sent events are a simpler alternative to Web Sockets for server push technology. Although some people seem convinced that bidirectional communication is an absolute necessity, many of the proposed use cases for Web Sockets are actually implementable using Server-Sent Events. This includes streaming stock quotes, score updates for games, bidding updates for auctions, etc. Opera 10.7 has an implementation of Server-Sent Events, and an implementation has already made it into the WebKit repository as well. Before jumping on the Web Sockets bandwagon, consider if Server-Sent Events can accomplish the same task.

Update (2010-Oct-22): Fixed typo.

Understanding JavaScript Promises E-book Cover

Demystify JavaScript promises with the e-book that explains not just concepts, but also real-world uses of promises.

Download the Free E-book!

The community edition of Understanding JavaScript Promises is a free download that arrives in minutes.