Должен ли быть один объект EventSource для каждого приложения?

При использовании Server-Sent Events клиент должен установить несколько подключений для получения различных событий, которые ему интересны, или должно быть одно соединение, а клиент указывает, что его интересует отдельный канал? IMO последнее кажется более предпочтительным, хотя для некоторых это может сделать код клиента более сложным. Спецификация поддерживает именованные события (события, относящиеся к определенной теме), которые, как мне кажется, предполагают, что соединение Server-Sent Events должно использоваться как один канал для всех событий.

Следующий код иллюстрирует первый сценарий, в котором инициируются несколько соединений с сервером отправленных событий:

var EventSource eventSource1 = new EventSource("events/topic1");
eventSource1.addEventListener('topic1', topic1Listener, false);

var EventSource eventSource2 = new EventSource("events/topic2");
eventSource2.addEventListener('topic2', topic2Listener, false);

eventSource1 получит события "topic1", а eventSource2 получит события "topic2". Хотя это довольно прямолинейно, он также довольно неэффективен, когда происходит зависание GET для каждой интересующей вас темы.

Альтернативой может быть следующее:

var EventSource eventSource3 = new EventSource("/events?id=1234")
eventSource3.addEventListener('topic3', topic3Listener, false);
eventSource3.addEventListener('topic4', topic4Listener, false);

var subscription = new XMLHttpRequest();
subscription.open("PUT", "/events/topic3?id=1234", true);
subscription.send();

В этом примере будет существовать один EventSource, и интерес к определенному событию будет задаваться отдельным запросом с соединением Event Server-Sent и регистрацией, которая коррелируется параметром id. topic3Listener получит события "topic3", а topic4Listener - нет. Хотя требуется немного больше кода, преимущество заключается в том, что выполняется только одно соединение, но события все еще можно идентифицировать и обрабатывать по-разному.

В Интернете есть несколько примеров, показывающих использование именованных событий, но кажется, что имена событий (или темы) известны заранее, поэтому нет необходимости, чтобы клиент регистрировал интерес к серверу (пример). Пока я еще не видел пример с несколькими объектами EventSource, я также не видел примера, показывающего клиента, использующего отдельный запрос для регистрации интереса к определенной теме, как я делаю выше. Моя интерпретация спецификации побуждает меня полагать, что указание интереса к определенной теме (или названию события) полностью зависит от разработчика и что ее можно сделать статически с клиентом, зная имена событий, которые он собирается получить или динамически с клиентом, предупреждающим сервер, что он заинтересован в получении определенных событий.

Мне было бы очень интересно услышать мысли других людей по этой теме. NB: Обычно я разработчик Java, поэтому, пожалуйста, простите мой посредственный JS-код..:)

Ответ 1

Я настоятельно рекомендую, IMHO, что у вас есть один объект EventSource для службы SSE-предоставления, а затем извещать сообщения с использованием разных типов.

В конечном счете, это зависит от того, насколько похожи типы сообщений. Например, если у вас есть 5 различных типов сообщений, связанных с пользователями, укажите пользователя EventSource и разделите его на типы событий.

Если у вас есть один тип событий о пользователях, а другой - о бутербродах, я бы сказал, сохраняйте их в разных службах и, таким образом, EventSource s.

Это хорошая идея подумать о том, чтобы разбить EventSources так же, как и на спокойный сервис. Если вы не получите две вещи из одной службы с AJAX, вы, вероятно, не должны получать их из одного и того же EventSource.

Ответ 2

В ответ на нечеткую и разрешительную стандартную интерпретацию браузера * поставщики браузеров недвусмысленно применяют ограничения на количество постоянных подключений, разрешенных для одного домена/порта. Поскольку каждый приемник событий в async-контексте предполагает одно постоянное распределение соединений до тех пор, пока этот приемник открыт, крайне важно, чтобы количество слушателей EventSource строго ограничено, чтобы избежать превышения различных ограничений, зависящих от поставщика. На практике это ограничивает примерно до 6 пар событий EventSource/async для каждого приложения. Деградация является изящной (например, дополнительные запросы на подключение к EventSource будут просто ждать, пока не будет доступен слот), но имейте в виду, что для получения ресурсов страницы, ответа на XHR и т.д. Должны быть доступны соединения.

* W3C выпустил стандарты в отношении постоянных соединений, которые содержат язык "... СЛЕДУЕТ ограничить количество одновременных подключений..." Этот язык означает, что стандарт не является обязательным, поэтому соответствие поставщика является переменной. http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4