WebSockets vs події, надіслані сервером / EventSource


838

Як WebSockets, так і серверні події можуть надсилати дані до браузерів. Мені вони здаються конкуруючими технологіями. У чому різниця між ними? Коли б ви вибрали одне над іншим?


2
Не впевнений, як ви бачите їх як змагаються. Один є синхронним і міг би / використовуватися для майже в реальному часі даних xfer, тоді як інший є асинхронним і слугуватиме зовсім іншому призначенню (ефективно надсилати тостоподібні повідомлення з додатка на сервері).
Брайан Дрісколл

54
WebSockets двосторонній, він може надсилати дані на сервер.
Андре Беклунд

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

7
@BrianDriscoll - асинхронний / синхронний - що це таке? Наскільки я можу зрозуміти, як включити асинхронні передачі?
Дейв Еверітт

5
SSE не працює на IE, веб-розетки
Тайлер Гілліс

Відповіді:


977

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

З'єднання веб-розетки можуть як надсилати дані до браузера, так і отримувати дані від браузера. Хорошим прикладом програми, яка може використовувати веб-розетки, є програма для чату.

З'єднання SSE можуть передавати дані лише в браузер. Котирування акцій в Інтернеті або щебетати, що оновлюють часові шкали або канал, є хорошими прикладами програми, яка може отримати користь від SSE.

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

Однак це може бути надмірним для деяких типів додатків, і бекенд може бути простіше реалізувати з таким протоколом, як SSE.

Крім того, SSE можна переповнити старими веб-переглядачами, які не підтримують його за допомогою JavaScript. Деякі реалізації поліелементів SSE можна знайти на сторінці Modernizr github .

Отримав:

  • SSE страждає від обмеження максимальної кількості відкритих з'єднань, що може бути особливо болючим при відкритті різних вкладок, оскільки обмеження визначено для браузера і встановлене на дуже низьке число (6). У Chrome і Firefox проблему було позначено як "Не вдасться виправити" . Цей ліміт призначений для одного браузера + домену, тобто це означає, що ви можете відкрити 6 SSE-з'єднань на всіх вкладках до www.example1.comта ще 6 підключень SSE www.example2.com(спасибі Phate).
  • Лише WS може передавати як бінарні дані, так і UTF-8, SSE обмежений UTF-8. (Спасибі Чадо Ніхі).
  • У деяких корпоративних брандмауерах при перевірці пакетів виникають проблеми з веб-розетками (брандмауер Sophos XG, WatchGuard, McAfee Web Gateway).

HTML5Rocks має хорошу інформацію про SSE. З цієї сторінки:

Події, надіслані сервером проти WebSockets

Чому б ви вибрали серверні події через WebSockets? Хороше питання.

Однією з причин, що SSE залишаються в тіні, є те, що пізніші API, такі як WebSockets, надають більш багатий протокол для здійснення двонаправленого, дуплексного зв'язку. Наявність двостороннього каналу привабливіше для таких речей, як ігри, додатки для обміну повідомленнями, а також для випадків, коли вам потрібно оновити в реальному часі в обох напрямках. Однак у деяких сценаріях дані не потрібно надсилати від клієнта. Вам просто потрібні оновлення від деяких дій сервера. Кілька прикладів - оновлення статусу друзів, біржові запаси, канали новин або інші автоматизовані механізми передачі даних (наприклад, оновлення клієнтської бази даних SQL на базі даних або об’єктного магазину IndexedDB). Якщо вам потрібно буде надіслати дані на сервер, XMLHttpRequest завжди є другом.

SSE передаються через традиційний HTTP. Це означає, що їм не потрібен спеціальний протокол або реалізація сервера для роботи. З іншого боку, для обробки протоколу WebSockets вимагають повного дуплексного з'єднання та нових серверів Web Socket. Окрім того, серверні події мають різні функції, яких WebSockets не вистачає в дизайні, такі як автоматичне повторне підключення, ідентифікатори подій та можливість надсилання довільних подій.


Підсумок TLDR:

Переваги SSE над Websockets:

  • Транспортується через простий HTTP замість спеціального протоколу
  • Можна наповнити javascript, щоб "підтримувати" SSE для браузерів, які ще не підтримують його.
  • Вбудована підтримка повторного підключення та ідентифікатора події
  • Простіший протокол
  • Немає проблем з корпоративними брандмауерами, які роблять перевірку пакетів

Переваги Websockets над SSE:

  • В режимі реального часу, двонаправлене спілкування.
  • Рідна підтримка у більшості браузерів

Ідеальні випадки використання SSE:

  • Поточний тикер потоку
  • оновлення каналу Twitter
  • Повідомлення для браузера

SSE отримали:

  • Немає бінарної підтримки
  • Максимальна межа відкритого з'єднання

131
Чат ідеально підходить за допомогою SSE - ви можете використовувати звичайні POST для надсилання повідомлень на сервер. Веб-розетки знадобляться лише в тому випадку, якщо ви реалізуєте чат Google Wave.
Корнель

135
Це правда, що чат та інші додатки в реальному часі можна робити за допомогою SSE. Однак для цього потрібні відповіді POSTing "поза діапазону", тобто це не контролюється протоколом SSE і не здається гарним прикладом для базового пояснення відмінностей між SSE та Websockets. Ви можете реалізовувати чат із основним опитуванням HTTP-сервера щосекунди та розміщенням нових відповідей. Це не означає, що це найкращий / найелегантніший спосіб зробити це.
Алекс Рекарей

14
Я вважаю, що рішення pomeL - це великий компроміс для більшості випадків, оскільки JS завжди може "поштовхнути" речі на сервер за допомогою AJAX POST. З мого досвіду, головним питанням було, як правило, потреба в JS для опитування нової інформації, але SSE опікується цим. : D
Якоб Притчетт

12
@MattDiPasquale Wave надіслала кожну клавішу окремо під час введення її замість повного повідомлення відразу. 200 байт накладних витрат на 1 натискання клавіші було б марно порівняно з 6 для WebSocket.
Корнель

9
Здається, трохи дивно сказати, що вони не є конкуруючими технологіями, а потім переходимо до опису, що їх можна використовувати як для досягнення подібних рішень. Я б сказав, що змушує їх змагатися.
Олексій

115

За інформацією caniuse.com:

Для розширення підтримки SSE для багатьох інших веб-переглядачів можна використовувати лише поліфункцію для клієнта. Це менш ймовірно для WebSockets. Деякі поліфіли EventSource:

Якщо вам потрібно підтримати всі браузери, подумайте про використання такої бібліотеки, як web-socket-js , SignalR або socket.io, яка підтримує численні перевезення, такі як WebSockets, SSE, Forever Frame та AJAX тривалого опитування. Вони також часто потребують модифікацій на стороні сервера.

Дізнайтеся більше про 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 Не треба лаятися. Якщо щось призначене для заміни попередньої версії, і це галузь прийнята і краще в усіх відношеннях, за визначенням, старий метод застарів. Так само, як оригінальний iPhone застарів, так і XHR. XHR вийшов перед Firefox, Chrome, першим iPhone, перед YouTube, Netflix, Facebook і навіть MySpace. Коли XHR вийшов Windows 98 був найкращою ОС, AOL був найкращим постачальником, а JSON навіть не існував. WebSockets замінив XHR майже десять років тому. Якщо ви натискаєте на корчі за допомогою WS, те, що спричинило її, також застаріло. Немає приводу відставати так далеко.
Нік Стіл

4
Тоді замініть BS на гіперболу :-) WS - це не заміна для XHR / HTTP більше, ніж дрони для автомобілів доставки. Це різні випадки використання. WS не є HTTP і має різні солодкі плями. Якщо ви спробуєте, ви повторно реалізуєте HTTP (погано) в просторі користувача. Крім того, ви маєте на увазі речі, які не мають фактів: WS - це просто двонаправлений протокол, що підтримує натиск сервера. Я ніколи не бачив, щоб жоден дизайнерський документ згадував, що він розробляється як заміна чого-небудь. Джерело? Вік сам по собі не є фактором. Коли вам надано вибір, виберіть найпростішу реалізацію, перевіряючи всі свої вимоги.
олігофрен

1
Лише два роки тому (2017) я налагоджував кучу відвалів Node JS-процесів, де код Socket.io викликав масштабну фрагментацію пам'яті в процесі IIS, закінчуючи спілкування безпосередньо з командою Node Azure. Загальна складність не є безкоштовною. Якщо ви можете піти з простого 20-рядкового сценарію, як залежність від сервера, і при цьому все ще можете обслуговувати 100K клієнтів, я б пішов на це. Я люблю WS за те, що робить, але погляньте на те, що вам потрібно, перш ніж вибирати рішення.
олігофрен

16

Opera, Chrome, Safari підтримує SSE, Chrome, Safari підтримує SSE всередині SharedWorker Firefox підтримує XMLHttpRequest readyState інтерактивним, тому ми можемо зробити EventSource поліфільмом для Firefox


8

Websocket VS SSE


Веб-розетки - це протокол, який забезпечує повнодуплексний канал зв'язку по одному TCP-з'єднанню. Наприклад, двосторонній зв'язок між сервером та браузером Оскільки протокол складніший, сервер і браузер повинні покладатися на бібліотеку веб-сокета, яка єsocket.io

Example - Online chat application.

SSE (Server-Sent Event) - У разі події, надісланої сервером, зв’язок здійснюється з сервера лише в браузер, і браузер не може надсилати будь-які дані на сервер. Цей вид зв'язку в основному використовується, коли потрібно лише показати оновлені дані, тоді сервер надсилає повідомлення щоразу, коли дані оновлюються. Наприклад, односторонній зв'язок між сервером та браузером. Цей протокол менш складний, тому не потрібно покладатися на зовнішню бібліотеку. Сам 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/isissue/94

Я припускаю, що з подіями, надісланими сервером, не так багато проблем. Але я не знаю.

Однак, WebSockets - це задоволення. У мене є маленька веб-гра, яка використовує websockets (через Socket.IO) ( http://minibman.com )


1
У мене також були проблеми з корпоративними брандмауерами.
олігофрен

1
Одне з проблем, які я бачив із подіями, надісланими сервером, - це те, що деякі проксі-сервіси / брандмауери можуть заблокувати його, оскільки в ньому немає заголовка довжини вмісту
Дрю Лесюер

2

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


-3

Максимальна межа з'єднання не є проблемою для http2 + sse.

Це було проблемою на http 1


Http2 дозволяє кілька запитів на одному домені трактуватись як потоки. Ця методика називається мультиплексуванням. Це дозволяє економити обмеження для веб-переглядача для кожного домену, і це є причиною, чому люди роблять заточування домену за допомогою Http1.
користувач1948585

1
Потоки HTTP / 2 також обмежені в кількості, це захищає сервери від бомбардування одним браузером і змушує браузери обмежувати їх мультиплексування обмеженою кількістю потоків - що, в нашому випадку, є таким же, як HTTP / 1.1 з'єднання .. , що повертає вас до межі з'єднання SSE.
Міст

Я припускаю, що підключення до веб-розетки також споживає ресурси сервера. samsaffron.com/archive/2015/12/29/websockets-caasure-required . Завжди добре мати можливість налаштувати стільки, скільки дозволяє ваш кишеню.
користувач1948585

цілком ймовірно, що SSE буде споживати подібні ресурси на більшості серверів (якщо не більше ресурсів через все ще присутній стек HTTP та його обмеження).
Міст

1
Ця відповідь правильна. Ліміт 6 HTTP-з'єднань більше не існує при використанні HTTP / 2. Доведення: codepen.io/dunglas/pen/yLYxdxK?editors=1010 За допомогою HTTP / 2 це сервер, і клієнт може узгодити максимальну кількість одночасних потоків (100 за замовчуванням).
Кевін Дунглас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.