HTML5 Server-Sent Events

There’s been a lot of talk lately about realtime web and WebSockets, but did you know that there exists an alternative HTML5 technology called EventSource that could handle some of the scenarios as well? EventSource is also called Server-Sent Events (SSE), a name that I prefer to use in order to avoid confusion with the larger architectural pattern called event sourcing.

The three things you should know about Server-Sent Events are: It’s..

  • uni-directional (only server push, initiated by client)
  • using pure HTTP
  • not using polling

The uni-directional constraint is not a problem, since the client still can GET data from the server or POST messages to the server, using XMLHttpRequest. Instead, let’s focus on the other two…

Image source: http://www.flickr.com/photos/davidw/171030064/

Pure HTTP

This feature is golden, because it has a lot of nice implications. First, even if SSE is not supported by all browsers, the fallback is just to start to use polling (polyfills for SSE are found here). Second, the integration story for other types of clients than browsers is better than websockets – no need for an websocket implementation on the client to be able to consume the events, just use HTTP. Third, it’s not an “all-or-nothing” approach like websockets – you can start with a naive server implementation and gradually improve it. I will explain this last statement in more detail below.

It’s not polling

Searching the web, it’s not a problem to find out how the data format for SSE looks like. I recommend to read the last part of section 7 of the specification for more details. However, it’s not clear how the connection between the client and the server is working. At first, I thought I just had bad luck in searching the net, but now I realize why there was not a single answer on how to think about the client/server connection. The answer? There is not one right answer, but rather several right answers, depending on your requirements.

First, let’s look at a sequence diagram using as much of SSE’s promises as possible. (The image is a link to a larger version)

In the diagram, we see that a connection is kept open as long as possible by the client/server pair and when the connection is closed (i.e. by a router, proxy, firewall, etc) the client reconnects to the server. As Damien Edward says on the excellent Hanselminutes episode about realtime web (I’m paraphrasing): SSE is similar to the long polling strategy, except that the connection is kept open as long as possible.

Begin simple

Keeping a connection opened as long as possible? That doesn’t scale! Yes and no. As Damien Edwards mentions in the Hanselminutes episode, in classical usage of ASP.NET this would be a problem, since every connection has a thread in the thread pool. If performance becomes a problem, one can refactor towards an asynchronous model, à la Node.js, which would reduce the memory footprint. But not every developer groks asynchronous design well, so there’s cost involved here as well. Of course, it depends a lot on your specific scenario, YMMV.

But there exists a still simpler solution: instead of keeping the connection open you can close it when you consider yourself done.

“Ahaha, that’s polling!” Yep, it is, and it’s very simple to implement and understand. And it has some potential problems, of course, but it all depends on what your scenario is. Perhaps it’s a sufficient design to use polling, both for user experience and performance?

A cool thing with SSE is that you can perform these refactorings on the server-side without changing the client side. “Upgrading” websockets in a similar way is not possible – either you use a websocket connection or you don’t. But then, if you know that [parts of] your web app is going to need “as much realtime as possible” and is expected to be used by many users at the same time, go for websockets.

There’s also an interesting possibility to use a more heterogeneous architectural style and use SSE on some parts of the app and websockets on other parts, depending on the scenarios and requirements.

Summary

Server-Sent Events is an interesting light-weight and refactoring friendly alternative to websockets and is worth investigating. It has a good 3rd party integration compared to websockets since SSE is using plain HTTP. And SSE is uni-directional, so the client needs to use XMLHttpRequest to communicate client-to-server.

Resources

W3C EventSource/Server-Sent Events Specification
http://www.w3.org/TR/eventsource/

When can I use Server-sent DOM events?
http://caniuse.com/eventsource

Damian Edwards explains The Realtime Web for ASP.NET with SignalR (audio podcast, recommended)
http://hanselminutes.com/291/damian-edwards-explains-the-realtime-web-for-aspnet-with-signalr

Real Time Rack (video presentation, recommended, start from 22:50 for non-Ruby content)
http://confreaks.com/videos/727-rockymtnruby2011-real-time-rack

HTML5 Rocks: Stream Updates with Server-Sent Events
http://www.html5rocks.com/en/tutorials/eventsource/basics/

Aslak Hellesøy compares WebSockets and Server-Sent Events and concludes that SSE have a better application-to-application integration story
https://github.com/aslakhellesoy/webbit-rest/wiki/Chat-Room-Example

StackOverflow: WebSockets vs. Server-Sent events/EventSource
http://stackoverflow.com/questions/5195452/websockets-vs-server-sent-events-eventsource

StackOverflow: What so different about Node.js’s event-driven? Can’t we do that in ASP.NET’s HttpAsyncHandler?
http://stackoverflow.com/questions/5599024/what-so-different-about-node-jss-event-driven-cant-we-do-that-in-asp-nets-ht

Jim Webber’s opinion about websockets
https://twitter.com/#!/jimwebber/status/172748058336034816

InfoQ: WebSockets versus REST
http://www.infoq.com/news/2012/02/websockets-rest

6 Comments

  1. For me EventSource seems like a half-way house with limited usage. Browser support is actually (marginally) better for WebSockets too:

    * http://caniuse.com/#search=eventsource
    * http://caniuse.com/#search=websockets

    The benefits of the realtime web are really about interaction and engagement. To achieve this you need two-way communication and that’s what WebSockets offer. For that reason I wouldn’t say EventSource is an alternative to WebSockets. For me, they are only useful for connecting and pushing data. That makes the use cases limited.

    One of the benefits of WebSockets is the lower latency. You connect, upgrade the connection from HTTP and from there messages are small with very little overhead. If you do open and close an connection with EventSource then you are introducing an overhead (HTTP headers) with those connections.

    You’ve probably noticed: I think we should be getting behind WebSockets :) Even the inventor of ‘Comet’ thinks that’s the case: http://www.leggetter.co.uk/2012/04/22/websockets-realise-comet-theyre-not-an-alternative.html#comment-518850026

    I do have to admit, however, that with the EventSource Polyfill (https://github.com/remy/polyfills/blob/master/EventSource.js) you probably get very close to 100% browser coverage. Whereas with the WebSockets one you are probably just high 90’s.

    Anyway, very informative post and very nice WebSequenceDiagrams – they are super-useful.

  2. Thank you for a great overview!
    I agree with Phil on the use of websequencediagrams, they’re super.
    On websockets vs SSE I definitely see a use case for SSE in some cases.

  3. @Phil, Thanks a lot for your comment! I’ll answer in a slightly different ordering..

    “You’ve probably noticed: I think we should be getting behind WebSockets :)”

    I agree. And I think we should be getting behind EventSource too, since they both have their pros and cons in different scenarios! :) If we can find scenarios where one is preferable over the other, we can make better decisions.

    “The benefits of the realtime web are really about interaction and engagement. To achieve this you need two-way communication and that’s what WebSockets offer. For that reason I wouldn’t say EventSource is an alternative to WebSockets. For me, they are only useful for connecting and pushing data. That makes the use cases limited.”

    We have two-way communication with EventSource+XMLHttpRequest, so the scenarios that are left IMO is the scenarios when you have lots of data client-to-server and it needs to “real” realtime. (i.e. games, some collaboration tools and perhaps trading apps). Can you think of more scenarios?

    “One of the benefits of WebSockets is the lower latency. You connect, upgrade the connection from HTTP and from there messages are small with very little overhead.”

    Yes, it’s a lower latency per message client-to-server, but not the other way = good for “real” realtime client-to-server.

    “If you do open and close an connection with EventSource then you are introducing an overhead (HTTP headers) with those connections.”

    If the event server is keeping the connection open, the number of HTTP requests will be exactly the same as in WebSockets.

    To summarize: As I see it, if the scenario is that you need “real” realtime for client-to-server communication, then go for WebSockets. Otherwise, EventSource/SSE is a technology you should consider evaluating.

  4. @Andreas Thanks a lot for your comment too! :)

  5. Nice explanation. It helped me a lot for implementing my own SSE service.

    In that case, thanks to Java Servlet 3.0+, I could manage to implement it asynchronously, so there is no need to waste threads in the Java server. If anyone can use it, it is freely available: http://github.com/mariomac/jeasse

Trackbacks for this post

  1. Competence weekend at Örenäs | Jayway Team Blog - Sharing Experience

Leave a Reply