Статьи

Использование отправленных сервером событий HTML5 с JSON и ASP.NET MVC

Я готовлюсь к сессии, которую я провожу в конце этого месяца. Я хотел создать пример использования событий, отправляемых с сервера HTML5, и решил поделиться этим примером с читателями моего блога. Но прежде чем я напишу об этом примере, давайте познакомимся с HTML5 API Server-Sent Events.

Отправленные сервером события

Отправленные сервером события — это аббревиатура от JavaScript API EventSource HTML5 . Отправленные сервером события позволяют серверам передавать данные по HTTP с использованием протоколов push. Данные, отправляемые на клиентскую сторону, должны иметь MIME-тип text / event-stream и должны отправляться в следующей форме:

data: This is the first message.

Обратите внимание, что формат должен включать данные: префикс и конец строки, чтобы завершить сообщение.

Другой способ отправки данных — использование выделенного события с использованием формата типа события. В следующем примере показаны два разных события, которые клиентская сторона может прослушивать:

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

Для прослушивания события на стороне клиента все, что вам нужно сделать, это создать объект EventSource и дать ему URL для прослушивания. Кроме того, вам необходимо подключить обработчик событий сообщения для обработки данных, поступающих с сервера. Вот простой пример создания объекта EventSource :

var source = new EventSource(url);

source.onmessage = function (e) {

    console.log(e.data);

}

Источником события по умолчанию является событие сообщения, как показано в предыдущем примере. Если вы хотите прослушивать определенный тип события, вам нужно подключить обработчик для этого типа события, как в следующем примере, который прослушивает событие event1 :

var source = new EventSource(url);

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

    console.log(e.data);

}, false);

Отправленные сервером события с использованием JSON и ASP.NET MVC

После того, как мы узнали, что такое Server-Sent Events, давайте погрузимся в более надежный пример. В этом примере я использую ASP.NET MVC в качестве серверной технологии.

Клиентская сторона

Мы начнем с реализации на стороне клиента. В представлении Index контроллера Home я добавлю неупорядоченный список сообщений и скрипт, который создает объект EventSource .

@{

    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>

Как видите, я использую событие DOMContentLoaded, чтобы запустить скрипт, когда весь контент DOM закончил загружаться. Я создаю EventSource с именем источника для прослушивания конечной точки home / message . Поскольку я ожидаю, что данные, возвращаемые с сервера, имеют формат JSON, я анализирую их с помощью функции JSON.parse и использую их содержимое для создания нового элемента списка.

Серверная сторона

Написание на стороне клиента было легко. Со стороны сервера также легко, но есть некоторые вещи, на которые стоит обратить внимание Прежде всего, я использую объект BlockingCollection, который является оберткой поверх коллекции IProducerConsumerCollection . Другой объект, который я использую, — это JavaScriptSerializer , который сериализует объект на сервере в представление JSON.
Вот код HomeController :

 

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");

    }

  }

}

Обратите внимание, что в
действии
Сообщение я возвращаю
тип контента
text / event-stream .

На следующем рисунке показан результат выполнения вышеуказанного кода:

Использование отправленных сервером событий HTML5 с объектами JSON

Резюме

Отправленные сервером события — это хороший механизм для передачи данных с сервера на клиент без необходимости опроса сервера. API обрабатывает только одну сторону связи (сервер-клиент). Если вы хотите использовать двунаправленный канал связи, вам следует обратиться к API веб-сокетов HTML5. Использование событий, отправленных сервером, подходит для прослушивания изменений в лентах новостей, таких как биржевая лента или лента RSS, если они реализуют протокол push.