Server-Sent Events in ASP.net MVC

Google Chrome (Chromium) recently released a version of their browser with support for server-sent events. I used this technology and ASP.net MVC to create a WebSlides application.

I created a nifty throw-away demo called WebSlides that switches between slides (PNG images). The slide show presenter navigates to a URL on their smart phone and is able to tap on back or forward links to change the current slide. The audience and the computer running the projector run a browser that points to another URL. As the presenter changes the slide all the clients connected see the updated slide.

What is a server-sent event?

Basically a server-sent event is a draft web standard that (on the ball) web browsers support to allow updates from the server to be “pushed” out to the browser. It is similar to WebSockets which has been all the rage (with cool experiments) but it is not a duplex communication channel. When you see the term “pushed” in regard to server-sent events you should note that what is actually happening is that the browser is actually polling a server URL. You can easily see this when you intercept traffic with fiddler. What it means though is you will not have to write the JavaScript to do the polling and it also gives you a way to only send data to the client when it is required. In my case I use it to update the slide the browser is showing when the presenter changes the slide.

How did I do it?

I created the WebSlides demo using ASP.net MVC, I believe I am the first to create something like this as support for server-sent events is pretty fresh. I found that this guy created a chat client with cold fusion on the server-side which is pretty cool.

In my demo I created a new ActionResult called ServerSentEventResult that does all the heavy lifting you need to do make the browser happy.

So all you have to do is use it like this in your controller.

ServerSentEventResult eventStream = new ServerSentEventResult();
Follower followerModel = new Follower();
eventStream.Version = followerModel.Version;
eventStream.Content = () =>
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    return serializer.Serialize(followerModel);
};

Another interesting point to note about my implementation is the lambda used to get the content, you may remember that the browser will poll the server to get events, so why make the server serialize data if it is not necessarily going to send it every request.

The rest of the magic happens on the client side with jQuery, If you have come this far I will leave it to you to dig around on github to see how that works.

5 thoughts on “Server-Sent Events in ASP.net MVC”

  1. It’s not quite right to say that the browser is polling the server with server-side events. The definition allows for the HTTP connection to stay open so that multiple events can be sent from the server to the browser with only a single request. I guess your solution looks like polling because ASP.Net is closing the HTTP connection after it has sent the response. The browser is then reconnecting at the specified interval (approx every 3 seconds). to see an example (in PHP) of the server holding the connection open so it can send multiple events, have a look at the code behind the HTML5Rocks sample SSE application at

    http://code.google.com/p/html5rocks/source/browse/www.html5rocks.com/content/tutorials/eventsource/basics/demo/sse.php

    In their example, the server keeps the connection open for 10 seconds, in which time it sends about 3 messages to the client. After the client realises the connection is closed, it re-establishes it automatically. This is the behaviour that looks like polling in your example.

      1. I’d be very interested to see if/how this could be done using WCF or ASP.Net. I’ve tried in WCF using a REST service with response streaming enabled, but the WCF processing pipeline disposes the response stream at some point once the stream has been read to the end, so you can’t just keep pushing events onto it :o(

        Would the idea of just writing to the response and never returning work in ASP.Net do you think (like the HTML5Rock solution)? I had a try, but it didn’t work immediately so I gave up because I was really focussing on WCF. This is because in my project I want to re-use existing WCF security.

    1. Great explanation Mike, thanks!
      I’ve been struggling to get this to work in ASP.NET MVC, but of course the result is definitely polling, and nothing like I would have expected from something named “server-sent events”.
      Up to this point I have’t found a workaround for this to work in ASP.NET MVC…

  2. Excellent example Keiran.
    I just realised I could use this technique for changing slides in higgins (my javascript based slide presenter), thus i could use my iphone as a remote control when presenting.

    in practice, it’s maybe too hard because i don’t want to rely on internet connectivity (or even a local wireless lan) during a talk.

    but an excellent example of a very powerful concept. cheers.
    lb

Leave a Reply