Протокол WebSockets проти HTTP


330

Існує багато блогів та дискусій про websocket та HTTP, і багато розробників та сайтів наполегливо виступають за веб-розетки, але я все ще не можу зрозуміти, чому.

наприклад (аргументи любителів веб-сокетів):

Веб-розетки HTML5 являє собою наступну еволюцію веб-комунікацій - повнодуплексний, двонаправлений канал зв'язку, який функціонує через один сокет через Інтернет. ( http://www.websocket.org/quantum.html )

HTTP підтримує потокову передачу: потокове запит тіла (ви використовуєте його під час завантаження великих файлів) та потокове тіло відповіді.

Під час з'єднання з WebSocket клієнт та сервер обмінюються даними на кадр, що становить 2 байти кожен, порівняно з 8 кілограмами заголовка http, коли ви здійснюєте постійне опитування.

Чому ці 2 байти не включають tcp та протоколи tcp накладні?

GET /about.html HTTP/1.1
Host: example.org

Це ~ 48 байт http заголовка.

Кодування кодування http - https://uk.wikipedia.org/wiki/Chunked_transfer_encoding :

23
This is the data in the first chunk
1A
and this is the second one
3
con
8
sequence
0
  • Отже, накладні витрати на кожен шматок не великі.

Також обидва протоколи працюють над TCP, тому всі проблеми TCP з довгими зв’язками все ще є.

Запитання:

  1. Чому протокол websockets краще?
  2. Чому він був реалізований замість оновлення протоколу http?

2
Яке Ваше запитання?
Йонас

@ Jonas, 1) чому протокол websockets краще? 2) Чому він був реалізований замість оновлення протоколу http? 3) Чому веб-розетки так рекламуються?
4esn0k

@JoachimPileborg, ви можете робити це з сокетами TCP або http також для настільних додатків; і вам потрібно використовувати WebRTC, щоб здійснити зв’язок браузер-браузер для веб-сайту
4esn0k

@JoachimPileborg, це webRTC для браузера, а не веб-розетки
4esn0k

@ 4esn0k, WS не кращий, вони різні та кращі для деяких конкретних завдань. 3) Це нова функція, про яку люди повинні знати і відкривати нові можливості для Інтернету
Jonas

Відповіді:


490

1) Чому протокол WebSockets краще?

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

Ваша передача HTTP в 48 байтів не є реальною для реальних підключень браузера HTTP, де часто є кілька кілобайт даних, що надсилаються як частина запиту (в обох напрямках), включаючи безліч заголовків та даних cookie. Ось приклад запиту / відповіді на використання Chrome:

Приклад запиту (2800 байт, включаючи дані cookie, 490 байт без файлів cookie):

GET / HTTP/1.1
Host: www.cnn.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.68 Safari/537.17
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: [[[2428 byte of cookie data]]]

Приклад відповіді (355 байт):

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 13 Feb 2013 18:56:27 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: CG=US:TX:Arlington; path=/
Last-Modified: Wed, 13 Feb 2013 18:55:22 GMT
Vary: Accept-Encoding
Cache-Control: max-age=60, private
Expires: Wed, 13 Feb 2013 18:56:54 GMT
Content-Encoding: gzip

І HTTP, і WebSockets мають еквівалентний розмір рукостискань з початковим з'єднанням, але при з'єднанні WebSocket початкове рукостискання виконується один раз, тоді невеликі повідомлення мають лише 6 байтів накладних витрат (2 для заголовка і 4 для значення маски). Затримка накладних витрат не стільки від розміру заголовків, скільки від логіки розбору / обробки / збереження цих заголовків. Крім того, затримка налаштування з'єднання TCP, ймовірно, є більшим фактором, ніж розмір або час обробки для кожного запиту.

2) Чому він був реалізований замість оновлення протоколу HTTP?

Докладаються зусилля для перепроектування протоколу HTTP для досягнення кращої продуктивності та зниження затримки, таких як SPDY , HTTP 2.0 та QUIC . Це поліпшить ситуацію для звичайних запитів HTTP, але ймовірно, що WebSockets та / або WebRTC DataChannel все ще матимуть меншу затримку для передачі даних клієнту на сервер, ніж протокол HTTP (або він буде використовуватися в режимі, який дуже схожий на WebSockets все одно).

Оновлення :

Ось основа для роздумів про веб-протоколи:

  • TCP : низькорівневий, двонаправлений, повнодуплексний і гарантований транспортний шар замовлення. Немає підтримки браузера (крім плагіна / Flash).
  • HTTP 1.0 : транспортний протокол на відповідь на запит, нанесений на TCP. Клієнт робить один повний запит, сервер дає одну повну відповідь, а потім з'єднання закривається. Методи запиту (GET, POST, HEAD) мають специфічне транзакційне значення для ресурсів на сервері.
  • HTTP 1.1 : підтримує характер відповіді на запит HTTP 1.0, але дозволяє з'єднанню залишатися відкритим для декількох повних запитів / повних відповідей (одна відповідь на запит). Все ще є повні заголовки у запиті та відповіді, але з'єднання повторно використовується та не закривається. HTTP 1.1 також додав деякі додаткові методи запиту (OPTIONS, PUT, DELETE, TRACE, CONNECT), які також мають специфічні транзакційні значення. Однак, як було зазначено у вступі до проекту пропозиції HTTP 2.0, трубопровід HTTP 1.1 не широко розгортається, тому це значно обмежує корисність HTTP 1.1 для вирішення затримок між браузерами та серверами.
  • Довге опитування : це "хак" для HTTP (або 1.0 або 1.1), коли сервер не відповідає негайно (або лише частково відповідає заголовами) на запит клієнта. Після відповіді сервера клієнт негайно надсилає новий запит (використовуючи те саме з'єднання, якщо над HTTP 1.1).
  • Потокова передача HTTP : різноманітні методи (багаточастинна / зв'язана відповідь), які дозволяють серверу надсилати більше одного відповіді на один запит клієнта. W3C стандартизує це як події, надіслані сервером, використовуючи text/event-streamтип MIME. API браузера (що досить схоже на API WebSocket) називається API EventSource.
  • Комета / серверний поштовх : це термін "парасолька", який включає як тривале опитування, так і протокол HTTP. Бібліотеки комети зазвичай підтримують декілька методик, щоб спробувати і максимально підтримувати крос-браузер і підтримку крос-сервера.
  • WebSockets : транспортний рівень, вбудований у TCP, який використовує рукостискання з підтримкою HTTP Upgrade. На відміну від TCP, який є потоковим транспортом, WebSockets - це транспорт на основі повідомлень: повідомлення розміщені на дроті та повторно збираються в повному обсязі перед доставкою до програми. З'єднання WebSocket двосторонні, повнодуплексні та довговічні. Після первинного запиту / відповіді рукостискання немає трансакційної семантики і дуже мало на кожне повідомлення. Клієнт і сервер можуть надсилати повідомлення в будь-який час і повинні обробляти отримання повідомлення асинхронно.
  • SPDY : Google ініціювала пропозицію розширити HTTP, використовуючи більш ефективний провідний протокол, але підтримуючи всю HTTP-семантику (запит / відповідь, cookie, кодування). SPDY вводить новий формат кадрування (з кадрами з попередньою фіксованою довжиною) і вказує спосіб накладання пар HTTP-запитів / відповідей на новий рівень кадрування. Заголовки можна стискати, а нові заголовки можна надсилати після встановлення з'єднання. Існують реальні впровадження SPDY у браузерах та серверах.
  • HTTP 2.0 : має подібні цілі, ніж SPDY: зменшити затримку HTTP та накладні витрати, зберігаючи HTTP-семантику. Поточний проект походить від SPDY і визначає рукостискання з оновленнями та обрамлення даних, що дуже схоже на стандарт WebSocket для рукостискання та кадрування. Альтернативна пропозиція проекту HTTP 2.0 (httpbis-speed-mobile) фактично використовує WebSockets для транспортного рівня і додає мультиплексування SPDY та відображення HTTP як розширення WebSocket (розширення WebSocket узгоджуються під час рукостискання).
  • WebRTC / CU-WebRTC : пропозиції, щоб дозволити рівний зв’язок між браузерами. Це може забезпечити низьке середнє та максимальне затримки зв'язку, оскільки основним транспортом є SDP / дейтаграма, а не TCP. Це дозволяє здійснювати доставку пакетів / повідомлень поза замовленням, що дозволяє уникнути випуску TCP затримок, спричинених скинутими пакетами, які затримують доставку всіх наступних пакетів (щоб гарантувати доставку замовлення).
  • QUIC : експериментальний протокол, спрямований на зменшення затримки в Інтернеті над протоколом TCP. На поверхні QUIC дуже схожий на TCP + TLS + SPDY, реалізований на UDP. QUIC забезпечує мультиплексування та контроль потоку, еквівалентний HTTP / 2, безпеку, еквівалентну TLS, і семантику підключення, надійність та еквівалент контролю перевантаженості TCP. Оскільки TCP реалізований в ядрах операційної системи та прошивці середньої скриньки, внесення значних змін у TCP поряд із неможливим. Однак оскільки QUIC побудований на версії UDP, він не має таких обмежень. QUIC розроблений та оптимізований для HTTP / 2 семантики.

Список літератури :


1
>> Однак це не допомагає затримці клієнта до сервера, що вимагає встановлення нового з'єднання для кожного повідомлення клієнт-сервер. - як щодо потокового реагування тіла? я знаю, XMLHttpRequest API цього не дозволяє, але воно існує. за допомогою потокової передачі на сервер ви можете передавати з клієнтської сторони.
4esn0k

8
@Philipp, він задав питання, яке я хотів би все-таки ретельно дослідити і документувати. Питання щодо WebSockets та інших механізмів на базі HTTP виникає досить часто, хоча тепер є хороша посилання на посилання. Але так, здається, ймовірно, що запитувач шукав доказів, щоб підкріпити заздалегідь уявлення про WebSockets проти HTTP, тим більше, що він ніколи не вибирав відповіді та не присуджував суму винагороди.
канака

9
Дуже дякую за цей дуже гарний та точний огляд протоколів.
Мартін Мізер

2
@WardC caniuse.com дають інформації про сумісності браузера ( в тому числі мобільних).
канака

3
@ www139, ні, на рівні протоколу WebSocket з'єднання залишається відкритим, поки одна сторона або інша сторона не закриє з'єднання. Можливо, вам також доведеться турбуватися про час очікування TCP (проблема з будь-яким протоколом на основі TCP), але будь-який трафік кожні хвилину або дві триматиме з'єднання відкритим. Насправді визначення протоколу WebSocket вказує тип кадру ping / pong, хоча навіть без цього ви могли б надіслати один байт (плюс два байтові заголовки), і це дозволить зберегти з'єднання відкритим. 2-3 байти кожні пару хвилин взагалі не є значним впливом на пропускну здатність.
канака

130

Ви, здається, припускаєте, що WebSocket є заміною HTTP. Це не. Це розширення.

Основним випадком використання WebSockets є програми Javascript, які працюють у веб-браузері та отримують дані в режимі реального часу від сервера. Ігри - хороший приклад.

До WebSockets єдиним методом взаємодії додатків Javascript із сервером був метод XmlHttpRequest. Але вони мають головний недолік: сервер не може надсилати дані, якщо клієнт прямо не вимагав цього.

Але нова функція WebSocket дозволяє серверу надсилати дані коли завгодно. Це дозволяє реалізовувати ігри на базі браузерів із значно меншою затримкою та без використання некрасивих хак, як-то AJAX для тривалого опитування чи плагіни браузера.

То чому б не використовувати звичайний HTTP з потоковими запитами та відповідями

У коментарі до іншої відповіді ви запропонували просто асинхронно передавати запит клієнта та орган відповіді.

Насправді WebSockets в основному це. Спроба відкрити підключення WebSocket від клієнта спочатку схожа на HTTP-запит, але спеціальна директива в заголовку (Upgrade: websocket) повідомляє серверу почати спілкуватися в цьому асинхронному режимі. Перші чернетки протоколу WebSocket були не набагато більше, ніж деякі рукостискання, щоб сервер зрозумів, що клієнт хоче спілкуватися асинхронно. Але тоді було зрозуміло, що проксі-сервери будуть заплутані цим, оскільки вони звикли до звичайної моделі запиту / відповіді HTTP. Розкрито потенційний сценарій атаки на проксі-сервери. Щоб запобігти цьому, необхідно було зробити трафік WebSocket схожим на будь-який звичайний трафік HTTP. Ось чому введені маскувальні клавішіостаточну версію протоколу .


>> сервер не може надсилати дані, якщо клієнт прямо не попросив цього; Веб-браузер повинен ініціювати з'єднання WebSockets ... те саме, що і для XMLHttpRequest
4esn0k

18
@ 4esn0k Браузер ініціює підключення до веб-розетки. Але після її встановлення обидві сторони можуть надсилати дані, коли вони захочуть. Це не стосується XmlHttpRequest.
Філіп

1
ЧОМУ це неможливо з HTTP?
4esn0k

4
@Philipp, ігри - хороший приклад, коли WebSockets блищать. Однак, це не реальний час дані з сервера, де ви отримуєте найбільший виграш. Ви можете отримати майже таку ж затримку сервера-> клієнта, використовуючи потокові протоколи HTTP / тривалі з'єднання. І з тривалими запитами сервери можуть ефективно надсилати щоразу, коли вони мають дані, оскільки клієнт уже надіслав запит, а сервер "тримає запит", поки не матиме дані. Найбільший виграш для WebSockets - це затримка клієнта> сервера (а отже, і зворотній шлях). Клієнт, який має змогу надсилати коли завгодно без накладних запитів - це справжній ключ.
канака

1
@Philipp, ще одна примітка: крім XMLHttpRequest та WebSockets для JavaScript для взаємодії з сервером є інші методи, включаючи приховані рамки кадрів та теги скриптів з довгим опитуванням. Докладнішу інформацію див. На сторінці Вікіпедії «Комета» для більш детальної інформації: en.wikipedia.org/wiki/Comet_(programming)
kanaka

27

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

http

За допомогою WebSockets, хоча спілкування все ще починається як початкове рукостискання HTTP, подальше оновлення слід дотримуватися протоколу WebSockets (тобто якщо і сервер, і клієнт відповідають протоколу, оскільки не всі організації підтримують протокол WebSockets).

Тепер за допомогою WebSockets можна встановити повний дуплекс і стійкий зв'язок між клієнтом і сервером. Це означає, що на відміну від запиту та відповіді, з'єднання залишається відкритим до тих пір, поки програма працює (тобто вона є постійною), а оскільки вона є дуплексною, можливе двостороннє одночасне спілкування, тобто зараз сервер здатний ініціювати комунікація та "підштовхує" деякі дані до клієнта, коли нові дані (що цікавлять клієнта) стають доступними.

веб-розетки

Протокол WebSockets є надзвичайним та дозволяє реалізувати схему обміну повідомленнями Publish-Subscribe (або Pub / Sub), яка є основною концепцією, що використовується в технологіях реального часу, де ви можете отримувати нові оновлення у вигляді натискання сервера без клієнт повинен повторно запитувати (оновити сторінку). Прикладами таких програм є відстеження місцеположення автомобіля Uber, повідомлення Push-сповіщень, оновлення цін на фондових ринках у режимі реального часу, чат, багатокористувацькі ігри, інструменти онлайн-співпраці в реальному часі тощо.

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

Ось відео з презентації, яку я зробив про WebSockets, і чим вони відрізняються, ніж використання звичайних API REST: Стандартизація та використання експоненціального збільшення потоку даних


24

Що стосується TL; DR, ось два центи та більш простий варіант для ваших питань:

  1. WebSockets надає ці переваги через HTTP:

    • Стійке стаціонарне з'єднання протягом тривалості з'єднання
    • Низька затримка: майже зв’язок у режимі реального часу між сервером / клієнтом через відсутність накладних витрат на відновлення з'єднань для кожного запиту, як цього вимагає HTTP.
    • Повний дуплекс: і сервер, і клієнт можуть надсилати / отримувати одночасно
  2. Протокол WebSocket і HTTP були розроблені для вирішення різних проблем, IE WebSocket був розроблений для поліпшення двонаправленої комунікації, тоді як HTTP був розроблений без стану, поширювався за допомогою моделі запиту / відповіді. Крім спільного використання портів із застарілих причин (брандмауер / проксі-проксі), не існує багато спільного підґрунтя для об'єднання їх в один протокол.


3
Важливо, що ви згадали термін "державний та без громадянства" у своєму порівнянні (Y)
Utsav T

15

Чому протокол websockets краще?

Я не думаю, що ми можемо порівнювати їх поряд із тим, хто кращий. Це не буде справедливим порівнянням просто тому, що вони вирішують дві різні проблеми . Їх вимоги різні. Це буде як порівняння яблук з апельсинами. Вони різні.

HTTP - протокол відповіді на запит. Клієнт (браузер) чогось хоче, сервер дає це. Це є. Якщо клієнт даних хоче великих розмірів, сервер може надіслати потокові дані, щоб позбутися небажаних проблем з буфером. Тут головна вимога або проблема полягає в тому, як зробити запит від клієнтів і як відповісти на ресурси (гібертекст), які вони запитують. Саме тут блищить HTTP.

У HTTP лише запит клієнта. Сервер відповідає лише.

WebSocket - це не протокол відповіді на запит, в якому може запитувати лише клієнт. Це розетка (дуже схожа на сокет TCP). Мається на увазі, коли з'єднання відкрите, будь-яка сторона може надсилати дані, поки підкреслити підключення TCP не буде закрито. Це як звичайна розетка. Єдина відмінність TCP-сокета - це вебсокет, який можна використовувати в Інтернеті. В Інтернеті у нас є великі обмеження для нормальної розетки. Більшість брандмауерів заблокує інші порти, ніж 80 та 433, які використовував HTTP. Проксі-сервери та посередники також будуть проблематичними. Отже, щоб зробити протокол простішим для розгортання до існуючої інфраструктури, веб-розетки використовують рукостискання HTTP для оновлення. Це означає, що коли вперше буде відкрито з'єднання, клієнт надіслав HTTP-запит, щоб повідомити серверу, кажучи: "Це не запит HTTP, будь ласка, перейдіть до протоколу websocket".

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Як тільки сервер зрозуміє запит і оновиться до протоколу websocket, жоден протокол HTTP вже не застосовується.

Тож моя відповідь: Ні один не кращий один за одного. Вони абсолютно різні.

Чому він був реалізований замість оновлення протоколу http?

Ми також можемо все зробити під ім'ям HTTP . Але чи будемо ми? Якщо це дві різні речі, я віддаю перевагу двом різним іменам. Так само роблять Хіксон та Майкл Картер .


6

Інші відповіді, схоже, не стосуються ключового аспекту, і це те, що ви не згадуєте про необхідність підтримки веб-браузера як клієнта. Більшість обмежень звичайного HTTP вище припускають, що ви працюєте з реалізаціями браузера / JS.

Протокол HTTP повністю здатний до повнодуплексного зв'язку; законно, щоб клієнт виконував POST з передачею кодованого фрагменту, а сервер повертав відповідь з тілом кодування, що кодується. Це призведе до видалення заголовка накладних, а саме до init.

Отже, якщо ви шукаєте лише дуплекс, керуйте і клієнтом, і сервером, і не зацікавлені в додаткових кадрах / особливостях веб-сокетів, то я б заперечив, що HTTP - це більш простий підхід із меншою затримкою / процесором (хоча затримка насправді відрізнятиметься лише в мікросекундах або менше для будь-якої).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.