WebSockets против событий, отправленных сервером / EventSource

839

И WebSockets, и события, отправленные сервером , могут передавать данные в браузеры. Мне они кажутся конкурирующими технологиями. В чем разница между ними? Когда бы вы выбрали один над другим?

Мадс Мобек
источник
2
Не уверен, как вы видите их как конкурирующих. Один из них является синхронным и может / мог бы использоваться для передачи данных почти в реальном времени, тогда как другой является асинхронным и будет использоваться для совершенно другой цели (эффективно отправляя похожие на тост сообщения из приложения на стороне сервера).
Брайан Дрисколл
54
WebSockets имеет две стороны, он может отправлять данные на сервер.
Андре Баклунд
13
Одна вещь, которая мне действительно нравится в SSE, - это то, что ее легко устранить ... просто откройте запрос на ваш сервер SSE, используя curl. Поскольку это просто текстовый формат по HTTP, легко увидеть, что происходит.
Сэм
7
@BrianDriscoll - асинхронный / синхронный - что есть что? Насколько я могу понять, как включить асинхронную передачу?
Дейв Эверитт
5
SSE не работает на IE, websockets работает
Тайлер Джиллис

Ответы:

980

Websockets и SSE (Server Sent Events) способны передавать данные в браузеры, однако они не являются конкурирующими технологиями.

Соединения через веб-сокеты могут отправлять данные в браузер и получать данные из браузера. Хорошим примером приложения, которое может использовать websockets, является приложение чата.

SSE-соединения могут передавать данные только в браузер. Онлайн котировки акций или твиттеры, обновляющие сроки или фид, являются хорошими примерами приложения, которое может извлечь выгоду из SSE.

На практике, поскольку все, что можно сделать с помощью SSE, можно также сделать с помощью Websockets, Websockets привлекает гораздо больше внимания и любви, и многие другие браузеры поддерживают Websockets, чем SSE.

Тем не менее, это может быть излишним для некоторых типов приложений, и бэкэнд может быть проще реализовать с помощью протокола, такого как SSE.

Кроме того, SSE можно использовать в старых браузерах, которые изначально не поддерживают его, используя только JavaScript. Некоторые реализации полизаполнений SSE можно найти на странице gizub Modernizr .

Gotchas:

  • SSE страдает от ограничения максимального количества открытых соединений, что может быть особенно болезненным при открытии различных вкладок, поскольку ограничение для каждого браузера установлено на очень низкое число (6). Эта проблема была помечена как «Не будет устранена» в Chrome и Firefox . Это ограничение на браузер + домен, так что это означает, что вы можете открыть 6 подключений SSE на всех вкладках www.example1.comи еще 6 подключений SSE www.example2.com(спасибо Phate).
  • Только WS может передавать как двоичные данные, так и UTF-8, SSE ограничен UTF-8. (Спасибо Чадо Нихи).
  • Некоторые корпоративные брандмауэры с проверкой пакетов испытывают трудности при работе с WebSockets (Sophos XG Firewall, WatchGuard, McAfee Web Gateway).

HTML5Rocks имеет хорошую информацию о SSE. С этой страницы:

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

Почему вы выбрали бы Отправленные сервером события вместо WebSockets? Хороший вопрос.

Одна из причин, по которой SSE остаются в тени, заключается в том, что более поздние API, такие как WebSockets, предоставляют более богатый протокол для двунаправленной полнодуплексной связи. Наличие двустороннего канала более привлекательно для таких вещей, как игры, приложения для обмена сообщениями, а также для случаев, когда вам нужны обновления в реальном времени в обоих направлениях. Однако в некоторых случаях данные не нужно отправлять с клиента. Вам просто нужны обновления от некоторых действий сервера. Примерами могут служить обновления статуса друзей, биржевые сводки, новостные ленты или другие автоматизированные механизмы передачи данных (например, обновление клиентской базы данных Web SQL или хранилища объектов IndexedDB). Если вам нужно отправить данные на сервер, XMLHttpRequest всегда будет вашим другом.

SSE передаются по традиционному HTTP. Это означает, что они не требуют специального протокола или серверной реализации для работы. WebSockets, с другой стороны, требуют полнодуплексных соединений и новых серверов Web Socket для обработки протокола. Кроме того, события, отправляемые сервером, имеют множество функций, которые отсутствуют в WebSockets, такие как автоматическое переподключение, идентификаторы событий и возможность отправлять произвольные события.


Резюме TLDR:

Преимущества SSE перед Websockets:

  • Транспортируется по простому HTTP вместо пользовательского протокола
  • Может быть заполнен javascript для «обратного переноса» SSE в браузеры, которые его еще не поддерживают.
  • Встроенная поддержка для повторного подключения и идентификатор события
  • Более простой протокол
  • Нет проблем с корпоративными брандмауэрами, выполняющими проверку пакетов

Преимущества веб-сокетов перед SSE:

  • В режиме реального времени два направления общения.
  • Встроенная поддержка в нескольких браузерах

Идеальные варианты использования SSE:

  • Поток тикера
  • обновление твиттера
  • Уведомления в браузер

SSE получил:

  • Нет бинарной поддержки
  • Максимальный предел открытых соединений
Алекс Ресари
источник
131
Общение с SSE вполне возможно - вы можете использовать обычный POST для отправки сообщений на сервер. WebSockets понадобятся только в том случае, если вы внедряете чат в Google Wave.
Корнель
135
Это правда, что чат и другие приложения в реальном времени могут быть сделаны с SSE. Однако это требует ответов POSTing «вне диапазона», т. Е. Это не контролируется протоколом SSE и не кажется хорошим примером для базового объяснения различий между SSE и Websockets. Вы можете реализовать чат с базовым HTTP-опросом сервера каждую секунду и отправкой новых ответов. Это не значит, что это лучший / самый элегантный способ сделать это.
Алекс Рекари
14
Я думаю, что решение pomeL является отличным компромиссом для большинства случаев, поскольку JS всегда может «вытолкнуть» вещи на сервер с помощью AJAX POST. Исходя из моего опыта, основной проблемой, как правило, была необходимость для JS опрашивать новую информацию, но SSE позаботится об этом. : D
Джейкоб Притчетт
12
@MattDiPasquale Wave отправлял каждый ключ индивидуально, когда вы его набирали, вместо полного сообщения сразу. 200 байтов служебной нагрузки POST на 1 нажатие клавиши были бы расточительными по сравнению с примерно 6 для WebSocket.
Корнель
9
Кажется немного странным сказать, что они не являются конкурирующими технологиями, а затем перейти к описанию того, что они могут быть использованы для достижения аналогичных решений. Я бы сказал, что это заставляет их конкурировать.
Алекс
115

По данным caniuse.com:

Вы можете использовать клиентский полифилл, чтобы расширить поддержку SSE для многих других браузеров. Это менее вероятно с WebSockets. Некоторые полифилы EventSource:

  • EventSource от Реми Шарпа без других библиотечных зависимостей (IE7 +)
  • jQuery.EventSource от Рик Уолдрон
  • EventSource на зеленый дятел (заменяет собственную реализацию, нормализующее поведение в разных браузерах)

Если вам необходимо поддерживать все браузеры, рассмотрите возможность использования библиотеки, такой как web-socket-js , SignalR или socket.io, которая поддерживает несколько транспортов, таких как WebSockets, SSE, Forever Frame и AJAX long polling. Они часто требуют изменений и на стороне сервера.

Узнайте больше о SSE от:

Узнайте больше о WebSockets от:

Другие отличия:

  • WebSockets поддерживает произвольные двоичные данные, SSE использует только UTF-8
Дрю Ноакс
источник
3
Я хотел бы отметить, что в 2016 году> 95% глобальных пользователей изначально поддерживают WebSockets. Все браузеры и устройства поддерживают WebSockets более 4 лет. Socket.IO откатится на долгий опрос AJAX и обработает сложности эмуляции WebSockets для вас, если он не поддерживается, что делает поддержку 100%. Если вы используете что-то кроме WebSockets в 2016 году, вы используете устаревшую технологию.
Ник Стил
3
@NickSteele Это глупое заявление об ажиотаже. Полагаться на старые стандарты - это прекрасно, если они соответствуют вашему варианту использования и не означают, что что-то устарело Это просто другой стандарт. Пример: XHR все еще может делать многое из того, что не может делать API Fetch, поэтому он не устарел. Это другое. Я использовал WS в прошлом, но по опыту знаю, что можно столкнуться с трудностями в виде шумовых корпоративных брандмауэров, которые блокируют запросы, когда он не понимает WS. SSE суперэффективен в том, что он делает, легко понять, реализовать и легко отладить. Для нашего одностороннего потока данных это идеально.
oligofren
@oligofren Не надо ругаться. Если что-то разработано, чтобы заменить предыдущую версию, и это принято в промышленности и лучше во всех отношениях, по определению, старый метод устарел. Как оригинальный iPhone устарел, так и XHR. XHR вышел до Firefox, Chrome, первого iPhone, до YouTube, Netflix, Facebook и даже MySpace. Когда вышел XHR, Windows 98 была лучшей ОС, AOL был лучшим провайдером, а JSON даже не существовало. WebSockets заменили XHR почти десять лет назад. Если вы ударили по заглушкам с помощью WS, то, что вызвало загвоздку, также устарело. Нет повода отставать так далеко.
Ник Стил
4
Тогда замените BS на Hyperbole :-) WS - это не замена XHR / HTTP, как беспилотники для машин доставки. Это разные варианты использования. WS не HTTP и имеют разные сладости. Вы бы в конечном итоге реализовали HTTP (плохо) в пространстве пользователя, если бы попытались. Кроме того, вы намекаете на то, что не соответствует действительности: WS - это просто двунаправленный протокол, поддерживающий продвижение сервера. Я никогда не видел, чтобы кто-нибудь из дизайнеров упоминал, что он разрабатывается как замена чего-либо. Источник? Возраст сам по себе не является фактором. Когда вам предоставляется выбор, выберите простейшую реализацию, проверяющую все ваши требования.
oligofren
1
Всего два года назад (2017 г.) я отлаживал дампы кучи процессов Node JS, в которых код Socket.io вызывал массовую фрагментацию памяти в процессе IIS, и в итоге общался напрямую с командой Azure Node. Общая сложность не бесплатная. Если вы можете обойтись без простого сценария из 20 строк, который зависит от сервера, и при этом обслуживать 100 000 клиентов, я бы пошел на это. Я люблю WS за то, что он делает, но посмотрите, что вам нужно, прежде чем выбрать решение.
oligofren
16

Opera, Chrome, Safari поддерживает SSE, Chrome, Safari поддерживает SSE внутри SharedWorker. Firefox поддерживает интерактивный XMLHttpRequest readyState, поэтому мы можем сделать EventSource polyfil для Firefox.

Зеленый дятел
источник
9

Websocket VS SSE


Веб-сокеты - это протокол, который обеспечивает полнодуплексный канал связи по одному TCP-соединению. Например, двусторонняя связь между сервером и браузером. Поскольку протокол более сложный, сервер и браузер должны полагаться на библиотеку веб-сокета, котораяsocket.io

Example - Online chat application.

SSE (отправленное сервером событие) - в случае отправленного сервером события связь осуществляется только с сервера на браузер, и браузер не может отправлять какие-либо данные на сервер. Этот вид связи в основном используется, когда нужно только показать обновленные данные, тогда сервер отправляет сообщение всякий раз, когда данные обновляются. Например, односторонняя связь между сервером и браузером. Этот протокол менее сложен, поэтому нет необходимости полагаться на внешнюю библиотеку. JAVASCRIPT сам предоставляет EventSourceинтерфейс для приема сообщений, отправленных сервером.

Example - Online stock quotes or cricket score website.
Гаурав Тивари
источник
4

Стоит отметить:
у меня были проблемы с веб-сокетами и корпоративными брандмауэрами. (Использование HTTPS помогает, но не всегда.)

См. Https://github.com/LearnBoost/socket.io/wiki/Socket.IO-and-firewall-software https://github.com/sockjs/sockjs-client/issues/94.

Я предполагаю, что с событиями, отправленными сервером, проблем не так много. Но я не знаю

Тем не менее, WebSockets тонны веселья. У меня есть небольшая веб-игра, которая использует веб-сокеты (через Socket.IO) ( http://minibman.com )

Дрю ЛеСюр
источник
1
У меня также были проблемы с корпоративными брандмауэрами.
oligofren
1
Одна проблема, которую я видел с событиями, отправленными сервером, заключается в том, что некоторые прокси / брандмауэры могут блокировать его, потому что у него нет заголовка Content-Length
Drew LeSueur
2

Здесь рассказывается о различиях между веб-сокетами и событиями, отправляемыми сервером. Начиная с Java EE 7 WebSocket API уже является частью спецификации, и кажется, что отправленные сервером события будут выпущены в следующей версии корпоративной версии.

Патрик Лейтерманн
источник
-3

Максимальный лимит соединения не проблема с http2 + sse.

Это была проблема на http 1

user1948585
источник
Http2 позволяет обрабатывать несколько запросов в одном домене как потоки. Эта техника называется мультиплексированием. Это сохраняет ограничения подключения браузера для домена, что является причиной, по которой люди используют разделение домена с помощью Http1.
user1948585
1
Количество потоков HTTP / 2 также ограничено, что защищает серверы от бомбардировки одним браузером и вынуждает браузеры ограничивать их мультиплексирование ограниченным числом потоков, что в нашем случае аналогично соединениям HTTP / 1.1. что возвращает вас к пределу соединения SSE.
Myst
Я предполагаю, что соединение с websocket также потребляет ресурсы сервера. samsaffron.com/archive/2015/12/29/websockets-caution-required . Всегда хорошо иметь возможность настроить столько, сколько позволяет ваш карман.
user1948585
вполне вероятно, что SSE будет использовать аналогичные ресурсы на большинстве серверов (если не больше ресурсов из-за все еще присутствующего стека HTTP и его ограничений).
Myst
1
Этот ответ правильный. При использовании HTTP / 2 ограничение в 6 HTTP-соединений больше не существует. Доказательство: codepen.io/dunglas/pen/yLYxdxK?editors=1010 С помощью HTTP / 2 сервер и клиент могут согласовывать максимальное количество одновременных потоков (по умолчанию 100).
Кевин Данглас