WebSockets против событий, отправленных сервером /EventSource
И WebSockets, и события, отправленные сервером, могут передавать данные в браузеры. Мне они кажутся конкурирующими технологиями. В чем разница между ними? Когда бы вы выбрали один над другим?
10 ответов
Websockets и SSE (Server Sent Events) способны передавать данные в браузеры, однако они не являются конкурирующими технологиями.
Соединения через веб-сокеты могут отправлять данные в браузер и получать данные из браузера. Хорошим примером приложения, которое может использовать websockets, является приложение чата.
Соединения SSE могут передавать данные только в браузер. Онлайн котировки акций или твиттеры, обновляющие сроки или фид, являются хорошими примерами приложения, которое может извлечь выгоду из SSE.
На практике, поскольку все, что можно сделать с помощью SSE, можно также сделать с помощью Websockets, Websockets привлекает гораздо больше внимания и любви, и многие другие браузеры поддерживают Websockets, чем SSE.
Тем не менее, это может быть излишним для некоторых типов приложений, и бэкэнд может быть проще реализовать с помощью протокола, такого как SSE.
Кроме того, SSE можно использовать в старых браузерах, которые изначально не поддерживают его, используя только JavaScript. Некоторые реализации полизаполнений SSE можно найти на странице gizub Modernizr.
Gotchas:
- SSE страдает от ограничения на максимальное количество открытых соединений, что может быть особенно болезненным при открытии различных вкладок, поскольку ограничение для каждого браузера установлено на очень низкое число (6). Эта проблема была помечена как "не будет устранена" в Chrome и Firefox
- Только WS может передавать как двоичные данные, так и UTF-8, SSE ограничен UTF-8. (Спасибо Чадо Нихи).
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 получил:
- Нет бинарной поддержки
- Максимальный предел открытых соединений
По данным caniuse.com:
- % 90 глобальных пользователей изначально поддерживают WebSockets
- % 84 глобальных пользователей изначально поддерживают отправленные сервером события
Вы можете использовать клиентский полифилл, чтобы расширить поддержку SSE для многих других браузеров. Это менее вероятно с WebSockets. Некоторые EventSource polyfills:
- EventSource от Реми Шарпа без других библиотечных зависимостей (IE7 +)
- jQuery.EventSource от Рик Уолдрон
- EventSource от Yaffle (заменяет собственную реализацию, нормализуя поведение в разных браузерах)
Если вам требуется поддержка всех браузеров, рассмотрите возможность использования библиотеки, такой как web-socket-js, SignalR или http://socket.io/, которая поддерживает несколько транспортов, таких как WebSockets, SSE, Forever Frame и AJAX long polling. Они часто требуют изменений и на стороне сервера.
Узнайте больше о SSE от:
- HTML5 Rocks статья
- Спецификация W3C ( опубликованная версия, черновик редактора)
Узнайте больше о WebSockets от:
- HTML5 Rocks статья
- Спецификация W3C ( опубликованная версия, черновик редактора)
Другие отличия:
- WebSockets поддерживает произвольные двоичные данные, SSE использует только UTF-8
В 2023 году ситуация не совсем такая, как раньше.
Несколько лет назад, когда IE все еще занимал значительную долю рынка, одним из недостатков SSE было полное отсутствие встроенной поддержки IE (тогда как WebSockets поддерживались IE 10+). В настоящее время, согласно caniuse.com, обе технологии почти одинаково хорошо поддерживаются на стороне клиента: 98,35% для WebSockets против 98,03% для SSE (эта статистика для глобальных пользователей).
Исторически сложилось одно серьезное ограничение SSE, ограничение в 6 подключений на домен (проблема, когдаyourapp.com
открывается во многих вкладках браузера) больше не проблема с. Все современные браузеры поддерживаютHTTP/2
(97,16% пользователей по всему миру) и на стороне сервераHTTP/2+
также превзошелHTTP/1
последние пару лет.
При выборе между SSE и WebSockets необходимо учитывать различные вещи:
- SSE, как правило, проще в реализации и проще в тестировании/отладке (простой
curl
может быть использован). - WebSockets поддерживают двунаправленную (полнодуплексную) связь. Тем не менее, SSE можно использовать в сочетании с AJAX, если требуется двусторонняя связь. В таких случаях часто говорят, что веб-сокеты являются более простым вариантом, но я думаю, что такие обобщения могут ввести в заблуждение, поскольку они во многом зависят от типа приложения, его дизайна и используемых технологий.
- SSE поддерживает только текстовые сообщения UTF-8, тогда как WebSockets также могут передавать двоичные данные.
- С практической точки зрения я бы также рекомендовал изучить, насколько хорошо ваш сервер приложений поддерживает каждую из этих технологий. Обратите внимание, что некоторые полагаются на дополнительные модули и/или библиотеки. Возможно, вы захотите взглянуть на некоторые примеры и, возможно, быстро создать PoC.
Websocket VS SSE
Веб-сокеты - это протокол, который обеспечивает полнодуплексный канал связи по одному TCP-соединению. Например, двусторонняя связь между сервером и браузером. Поскольку протокол более сложный, сервер и браузер должны полагаться на библиотеку веб-сокета, которая socket.io
Example - Online chat application.
SSE(отправленное сервером событие) - в случае отправленного сервером события связь осуществляется только с сервера на браузер, и браузер не может отправлять какие-либо данные на сервер. Этот вид связи в основном используется, когда нужно только показать обновленные данные, тогда сервер отправляет сообщение всякий раз, когда данные обновляются. Например, односторонняя связь между сервером и браузером. Этот протокол менее сложен, поэтому нет необходимости полагаться на внешнюю библиотеку, которую сам JAVASCRIPT предоставляет EventSource
интерфейс для приема на сервер отправленных сообщений.
Example - Online stock quotes or cricket score website.
Opera, Chrome, Safari поддерживает SSE, Chrome, Safari поддерживает SSE внутри SharedWorker. Firefox поддерживает интерактивный XMLHttpRequest readyState, поэтому мы можем сделать EventSource polyfil для Firefox.
Стоит отметить:
У меня были проблемы с веб-сокетами и корпоративными брандмауэрами. (Использование 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/)
они разные по семантике.
websocket имеет собственное семантическое значение «двунаправленный поток данных».
в то время как sse имеет собственное семантическое значение «шаблон публикации-подписки».
конечно, вы можете реализовать слой «шаблона публикации-подписки» через веб-сокет самостоятельно. но это менее изящно и менее эффективно.
в изящной программе реализация должна соответствовать семантике.
WebSocket и SSE являются альтернативами традиционной веб-архитектуре "запрос-ответ", но они не совсем конкурирующие технологии. Архитектура WebSocket состоит из сокета, который открывается между клиентом и сервером для полнодуплексной (двунаправленной) связи. Вместо отправки сообщения GET и ожидания ответа сервера клиент просто слушает сокет, получает обновления сервера и использует данные для инициирования или поддержки различных взаимодействий. Клиент также может использовать сокет для связи с сервером, например, отправив сообщение ACK, когда обновление было успешно получено.
SSE - это более простой стандарт, разработанный как расширение HTML5. Хотя SSE разрешает асинхронные сообщения с сервера на клиент, клиент не может отправлять сообщения на сервер. Модель полудуплексной связи SSE лучше всего подходит для приложений, в которых клиенту просто необходимо получать потоковые обновления с сервера. Одним из преимуществ SSE по сравнению с WebSocket является то, что он работает по HTTP, не требуя дополнительных компонентов.
Для многоцелевого веб-приложения, требующего обширной связи между клиентом и сервером, WebSocket является очевидным выбором. SSE больше подходит для приложений, которые хотят передавать асинхронные данные клиенту с сервера, но не требуют ответа.
Максимальный лимит соединения не является проблемой с http2 + sse.
Это была проблема на http 1