HTML5 Zone is brought to you in partnership with:

Gil Fink, Microsoft MVP, is an expert in Web development and Microsoft data platform. He works as a senior architect at Sela Group. He is currently consulting for various enterprises and companies, where he architects and develops Web and RIA-based solutions. He conducts lectures and workshops for developers and enterprises who want to specialize in infrastructure and Web development. He is also a co-author of several Microsoft Official Courses and training kits. You can read his publications at his blog: http://blogs.microsoft.co.il/blogs/gilf. Gil is a DZone MVB and is not an employee of DZone and has posted 147 posts at DZone. You can read more from them at their website. View Full User Profile

Using HTML5 Server-Sent Events with JSON and ASP.NET MVC

04.11.2012
| 5244 views |
  • submit to reddit

I’m getting ready for a session that I’m delivering at the end of this month. I wanted to create a sample for using HTML5 Server-Sent Events and decided to share that sample with my Blog’s readers. But before I write about the sample, lets get to know the Server-Sent Events HTML5 API.

Server-Sent Events

Server-Sent Events is an acronym to the HTML5 EventSource JavaScript API. The Server-Sent Events enable servers to push data over HTTP using push protocols. The data that is sent to the client-side must have the text/event-stream MIME type and must be sent in the following form:

data: This is the first message.

Pay attention that the format has to include the data: prefix and end with line break to end the message.

Another way to send data is using a dedicated event by using the event type format. The following example shows two different events that the client-side can listen for:

event: event1
data: event1 data
 
event: event2
data: event2 data

In order to listen to an event in the client-side all you have to do is to create an EventSource object and give it a URL to listen. Also, you need to wire the message event handler in order to handle the data arriving from the server. Here is a simple example of creating an EventSource object:

var source = new EventSource(url);

source.onmessage = function (e) {

    console.log(e.data);

}

The default event source is the message event as shown in the previous example. If you want to listen for a specific event type you will need to wire a handler for that event type like in the following example which listen on the event1 event:

var source = new EventSource(url);

source.addEventListener('event1', function (e) {

    console.log(e.data);

}, false);

Server-Sent Events Using JSON and ASP.NET MVC

After we learned what are Server-Sent Events lets dive into a much more robust example. In the example, I use ASP.NET MVC as my server side technology.

The Client-Side

We start in the client-side implementation. In the Index view of the Home controller I’ll add an messages unordered list and the script that creates the EventSource object.

@{

    ViewBag.Title = "Home Page";

}

<script>

   1:  

   2:     function contentLoaded() {

   3:         var source = new EventSource('home/message');

   4:         var ul = document.getElementById("messages");

   5:         source.onmessage = function (e) {

   6:             var li = document.createElement("li");

   7:             var returnedItem = JSON.parse(e.data)

   8:             li.textContent = returnedItem.message + ' ' + returnedItem.item;

   9:             ul.appendChild(li);

  10:         }

  11:     }

  12:  

  13:     window.addEventListener("DOMContentLoaded", contentLoaded, false);

</script>

<h2>@ViewBag.Message</h2>

<p>

    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">

        http://asp.net/mvc</a>.

</p>

<ul id="messages">

</ul>

As you can see I use the DOMContentLoaded event to start the script when all the DOM content finished to load. I’m creating an EventSource with the name source to listen to the home/message endpoint. Since I expect that the data returned from the server is in JSON format, I parse it using the JSON.parse function and use its content to create a new list item.

The Server-Side

Writing the client-side was easy. The server side is also easy but there are some things to notice. First of all, I use a BlockingCollection object which is a wrapper on top of a IProducerConsumerCollection collection. Another object that I use is the JavaScriptSerializer that will serialize an object on the server to JSON representation.
Here is the HomeController code:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Collections.Concurrent;

using System.Text;

using System.Threading;

using System.Web.Script.Serialization;

 

namespace ServerSentEvents.Controllers

{

  public class HomeController : Controller

  {

    private static BlockingCollection<string> _data = new BlockingCollection<string>();

 

    static HomeController()

    {

      _data.Add("started");

      for (int i = 0; i < 10; i++)

      {

        _data.Add("item" + i.ToString());

      }

      _data.Add("ended");

    }

 

    public ActionResult Index()

    {

      ViewBag.Message = "Welcome to ASP.NET MVC!";

 

      return View();

    }

 

    public ActionResult About()

    {

      return View();

    }

 

    public ActionResult Message() 

    {

      var result = string.Empty;

      var sb = new StringBuilder();

      if (_data.TryTake(out result, TimeSpan.FromMilliseconds(1000)))

      {

        JavaScriptSerializer ser = new JavaScriptSerializer();

        var serializedObject = ser.Serialize(new { item = result, message = "hello" });

        sb.AppendFormat("data: {0}\n\n", serializedObject);

      }

      return Content(sb.ToString(), "text/event-stream");

    }

  }

}

Pay attention that in the Message action I’m returning the text/event-stream content type.

The following figure shows the output of running the above code:

Using HTML5 Server-Sent Events with JSON Objects

Summary

Server-Sent Events is a good mechanism to push data from the server to the client without the need server polling. The API handles only one side communication (server to client). If you want to use a bidirectional communication channel you should look at the HTML5 Web Sockets API. Using Server-Sent Events is appropriate for listening for changes in feeds such as stocks feed or RSS feed as long as they implement the push protocol.

Published at DZone with permission of Gil Fink, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)