Server-sent events

HTTP is a client-server protocol — the client makes a request and the server replies with a response. For some applications, though, the request-reply model is limiting or unsuitable. These applications tend to want server-to-client notification capabilities. While such notifications can be simulated using polling, and web-based polling can be much more efficient than one would think due to intermediary caching, it's still less efficient and less timely than a notification model.

Yaws users have a few options for notification-oriented applications:

Currently, Chrome, Firefox, Opera, and Safari support SSE. Older browsers do not support SSE directly, but they can be made to do so with suitable JavaScript packages.

Writing a Yaws SSE application

Yaws supports SSE through its streaming capabilities. SSE applications typically consist of an entry point page and an appmod. The entry page returns HTML and JavaScript that acts as the SSE client, with the JavaScript invoking the appmod's out/1 function that creates a streaming process responsible for sending events back to the client. The appmod uses the yaws_sse module to properly format and send its event data.

Yaws supplies an example that uses SSE to return the server's time of day clock to the client. Each second, the server sends a new event to the client updating its time of day, which the client dynamically displays in a web page.

Note: if you're running this on your own Yaws installation, make sure your server configuration includes the following appmod entry:

appmods = <"/sse", server_sent_events>

and also make sure server_sent_events.beam is on the Yaws load path, which it should be if you followed regular installation procedures.

First, the entry HTML page is here: server_sent_events.html. It presents a page title and a placeholder for the server date string. It also supplies a bit of JavaScript that receives events from Yaws, using the browser's EventSource JavaScript class to receive them. It then pulls the data out of the event and displays it dynamically in the HTML.

Next, the server appmod code is here: server_sent_events.erl. Its out/1 function create a gen_server event generation process, returning the pid in a streamcontent_from_pid directive to Yaws along with suitable headers. Note that it obtains the desired out/1 return value via the yaws_sse:headers/1 function. Its gen_server is fairly simple in that it creates a timer that, once per second, generates a time of day string and sends it as an event to the client formatted via the yaws_sse:data/1 function.

The yaws_sse module supplies all the SSE primitives required for formatting event data, event identifiers, and event retry settings. See the Server-Sent Events working draft for more details on using these features.

The yaws_sse module also supplies functions for formatting and sending event data on a socket. If you're using the yaws_sse module outside of a Yaws streaming application, you should use the arity 3 version of yaws_sse:send_events and pass fun yaws:gen_tcp_send/2 as the third argument.

Note: be aware that because the W3C Server-Sent Events spec is still a working draft, any future changes in it might cause API-incompatible changes in how Yaws supports it.

Valid XHTML 1.0!