Моє розуміння опитування HTTP, тривалого опитування, потоку HTTP та веб-сокетів


123

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

HTTP опитування: в основному AJAX, використовуючи XmlHttpRequest.

Http Long Polling: AJAX, але сервер тримається на відповідь, якщо сервер не має оновлення, як тільки сервер має оновлення, він надсилає його і тоді клієнт може надіслати ще один запит. Недоліком є ​​додаткові дані заголовка, які потрібно надсилати назад і назад, викликаючи додаткові накладні витрати.

Потокова передача Http: Подібно до тривалого опитування, але сервер відповідає заголовком із "Переносом кодування: фрагменти", і тому нам не потрібно ініціювати новий запит щоразу, коли сервер надсилає якісь дані (а значить, зберігати додаткові накладні заголовки). Недолік тут полягає в тому, що ми маємо "зрозуміти" і розібратися в структурі даних, щоб розрізняти кілька фрагментів, що надсилаються сервером.

Java Applet, Flash, Silverlight: Вони надають можливість підключатися до серверів сокет через tcp / ip, але оскільки вони плагіни, розробники не хочуть залежати від них.

WebSockets: це новий API, який намагається вирішити короткі надходження вищезгаданих методів таким чином:

  • Єдина перевага WebSockets над плагінами, такими як Java Applets, Flash або Silverlight, полягає в тому, що WebSockets вбудовані в браузери і не покладаються на плагіни.
  • Єдина перевага WebSockets над потоком http полягає в тому, що вам не доведеться докладати зусиль, щоб "зрозуміти" та проаналізувати отримані дані.
  • Єдиною перевагою WebSockets над Long Polling є виключення зайвих розмірів заголовків та відкриття та закриття підключення сокета для запиту.

Чи є якісь інші суттєві відмінності, які мені не вистачає? Вибачте, якщо я перепитую або поєдную багато запитань, які вже є на ЗО, в одне запитання, але я просто хочу мати ідеальний сенс з усієї інформації, яка там знаходиться в СО та Інтернеті щодо цих понять.

Дякую!


4
Події, надіслані сервером, можуть також варто переглянути, коли вам не потрібно двостороннє спілкування.
легетер

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

@leggetter Дякую Філ, дякую за пораду щодо подій, що надсилаються сервером. Мені цікаво дізнатися про двонаправлені сценарії спілкування. Дякую.
Програмне забезпечення Гай

1
За допомогою HTTP Streaming та Long-Polling вам потрібно 2-е з'єднання для двостороннього зв’язку. Одне триваліше з'єднання для сервера -> клієнтське "натискання" зв'язку та друге короткочасне з'єднання для клієнта -> серверне сполучення. Це друге з'єднання використовується для таких дій, як налаштування та зміна підписки на дані. Таким чином, EventSource може бути використаний у двосторонньому рішенні, і фактично це стандартизоване рішення, народжене за допомогою HTTP Streaming та Long-Polling.
легетер

1
Ви також можете перевірити цю класифікацію методів я писав: stackoverflow.com/questions/12078550 / ...
Алессандро Alinone

Відповіді:


92

Існує більше відмінностей, ніж ті, які ви визначили.

Дуплекс / напрямок:

  • Одностороннє: опитування HTTP, тривале опитування, потокове передавання.
  • Двонаправлення: WebSockets, плагінова мережа

У порядку збільшення затримки (приблизно):

  • WebSockets
  • Підключення до плагінів
  • Потокове передавання HTTP
  • Довге опитування HTTP
  • Опитування HTTP

CORS (підтримка перехресного походження):

  • WebSockets: так
  • Мережа плагінів: Flash через запит політики (не впевнений у інших)
  • HTTP * (деяка нещодавня підтримка)

Рідні двійкові дані (набрані масиви, краплі):

  • WebSockets: так
  • Мережа плагінів: не за допомогою Flash (потрібне кодування URL-адрес у ExternalInterface)
  • HTTP *: нещодавня пропозиція включити підтримку бінарного типу

Пропускна здатність при зниженні ефективності:

  • Мережа за допомогою плагінів: Flash-розетки є сирими, крім початкового запиту політики
  • WebSockets: рукостискання налаштування з'єднання та кілька байт на кадр
  • Потокове передавання HTTP (повторне використання підключення до сервера)
  • HTTP-довге опитування: з'єднання для кожного повідомлення
  • Опитування HTTP: з'єднання для кожного повідомлення + повідомлення без даних

Підтримка мобільних пристроїв:

  • WebSocket: iOS 4.2 та новіших версій. Деякі Android через емуляцію Flash або використання Firefox для Android або Google Chrome для Android, які підтримують вбудовану підтримку WebSocket.
  • Мережі для плагінів: деякі Android. Не на iOS
  • HTTP *: переважно так

Складність використання Javascript (від найпростішого до найскладнішого). Слід визнати, що заходи щодо складності дещо суб'єктивні.

  • WebSockets
  • Опитування HTTP
  • Підключення до плагінів
  • Довге опитування HTTP, потокове

Також зауважте, що існує пропозиція W3C щодо стандартизації потоку HTTP під назвою " Події, надіслані сервером" . Наразі це досить рано в процесі еволюції, і він призначений для надання стандартного API Javascript із порівнянною простотою з WebSockets.


1
Дуже дякую за гарну відповідь Kanaka. Скажіть, будь ласка, чому / як http-потоки має більшу затримку, ніж веб-розетки? може, з простим прикладом? дуже дякую.
Програмне забезпечення Гай

2
@SoftwareGuy. Багато причин. У останніх браузерах ви можете використовувати обробник подій XMLHTTPRequest про прогрес, щоб отримувати повідомлення про дані. Але специфікація каже, що 50 мс - це найменший інтервал сповіщень. В іншому випадку потрібно опитуватись щодо даних відповідей. Також клієнт відправляє встановити нове HTTP-з'єднання і настільки значно збільшить затримку в обидва кінці. Крім того, багато веб-серверів відключають HTTP-з'єднання через 30 секунд або близько того, що вам часто доводиться продовжувати налагоджувати з'єднання із сервером. Я бачив затримки в зворотному напрямку на 5-10ms WebSocket в локальній мережі. Затримка потокової передачі HTTP, ймовірно, становитиме 50 мс +.
канака

Дякую за детальну відповідь :)
Software Guy

1
@leggetter Спасибі Філ, ти маєш на увазі, що надсилання даних від клієнта на сервер через http-потоки спричинить накладні витрати? чи можлива передача даних на сервер навіть через потокове http без відкриття нового з'єднання? Дякую.
Програмне забезпечення Гай

1
@Nathan звучить як хороший проект магістерської дипломної роботи! Безумовно, опитування дозволить зберегти систему зайнятішою, ніж модель, керована подіями, але для того, що саме може бути економія енергії, знадобиться досить широке емпіричне тестування в різних масштабах.
канака

13

Деякі чудові відповіді від інших, які накривають багато підстав. Ось трохи зайвого.

Єдина перевага WebSockets над плагінами, такими як Java Applets, Flash або Silverlight, полягає в тому, що WebSockets вбудовані в браузери і не покладаються на плагіни.

Якщо під цим ви маєте на увазі, що ви можете використовувати Java Applets, Flash або Silverlight для встановлення з'єднання з сокетом, то так, це можливо. Однак ви не бачите цього в реальному світі занадто часто через обмеження.

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

Більше того, WebSocket може використовувати порт 80 і 443, не вимагаючи виділених портів, знову ж таки завдяки дизайну протоколу бути максимально сумісним з існуючою HTTP-інфраструктурою.

Ці альтернативні розетки (Java, Flash та Silverlight) важко безпечно використовувати в архітектурі перехресного походження. Таким чином, люди, які часто намагаються використовувати їх перехресне походження, будуть терпіти невпевненість, а не намагатися робити це безпечно.

Вони також можуть вимагати відкриття додаткових "нестандартних" портів (те, що адміністратори ненавидять робити) або файлів політики, якими потрібно керувати.

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

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

Деякі реалізації WebSocket використовують Flash (або, можливо, Silverlight та / або Java) як резервну копію, коли підключення до WebSocket неможливо встановити (наприклад, при запуску в старому браузері або коли втручається посередник).

Хоча якась стратегія резервного копіювання для цих ситуацій розумна, навіть необхідна, більшість тих, хто використовує Flash et al, будуть страждати від описаних вище недоліків. Це не повинно бути таким чином - існують шляхи вирішення способів досягнення безпечних з'єднань, здатних до перехресного походження, використовуючи Flash, Silverlight тощо.

Наприклад, якщо ви покладаєтесь на WebSocket для перехресного походження, це буде добре. Але якщо ви запускаєте старий веб-переглядач або втручаєтеся брандмауер / проксі і покладаєтесь на Flash, скажімо, як ваш резервний запас, вам буде складно виконати те саме підключення між походженнями. Якщо, звичайно, ви не дбаєте про безпеку.

Це означає, що складно створити єдину об'єднану архітектуру, яка працює для рідних і не рідних зв’язків, якщо тільки ви не готові вкласти чимало роботи або не виконати рамки, які це зробили добре. В ідеальній архітектурі ви не помітили б, чи з'єднання були рідними чи ні; ваші налаштування безпеки будуть працювати в обох випадках; ваші налаштування кластеризації все одно будуть працювати; ваше планування потенціалу все ще буде дотримано; і так далі.

Єдина перевага WebSockets над потоком http полягає в тому, що вам не доведеться докладати зусиль, щоб "зрозуміти" та проаналізувати отримані дані.

Це не так просто, як відкривати потік HTTP і сидіти, коли ваші дані протікають хвилин, годин або довше. Різні клієнти поводяться по-різному, і ви повинні цим керувати. Наприклад, деякі клієнти завантажують дані в буфер і не передають їх у додаток, поки не буде досягнуто певного порогу. Ще гірше, що деякі не передадуть дані програмі, поки з'єднання не буде закрито.

Отже, якщо ви надсилаєте декілька повідомлень до клієнта, можливо, клієнтська програма не отримає дані, доки, наприклад, не буде отримано 50 повідомлень на суму. Це не надто в режимі реального часу.

Хоча потокове передавання HTTP може бути життєздатною альтернативою, коли WebSocket недоступний, це не панацея. Потрібно добре розуміння, щоб надійно працювати в неплотних місцях Мережі в реальних умовах.

Чи є якісь інші суттєві відмінності, які мені не вистачає?

Є ще одна річ, про яку ще ніхто не згадував, тому я підведу це.

Протокол WebSocket був розроблений як транспортний рівень для протоколів вищого рівня. Хоча ви можете надсилати повідомлення JSON чи що інше безпосередньо через з'єднання WebSocket, воно також може переносити стандартні або спеціальні протоколи.

Наприклад, ви можете робити AMQP або XMPP через WebSocket, як це вже робили люди. Таким чином клієнт міг отримувати повідомлення від брокера AMQP так, ніби він був підключений безпосередньо до самого брокера (а в деяких випадках і є).

Або якщо у вас є існуючий сервер з певним користувальницьким протоколом, ви можете транспортувати його через WebSocket, тим самим поширивши цей бек-сервер в Інтернет. Часто наявна програма, що була заблокована на підприємстві, може розширити сферу її дії за допомогою WebSocket, не змінюючи жодної інфраструктури.

(Зрозуміло, ви хочете мати можливість зробити все це надійно, тому зверніться до постачальника чи постачальника WebSocket.)

Деякі люди називають WebSocket як TCP для Інтернету. Тому що, як і TCP транспортує протоколи вищого рівня, так і WebSocket, але таким чином, що він сумісний з веб-інфраструктурою.

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

Вибачте, якщо я перепитую або поєдную багато запитань, які вже існують на ЗП, в одне запитання, але я просто хочу отримати ідеальний сенс з усієї інформації, яка там знаходиться в СО та Інтернеті щодо цих понять.

Це було чудове запитання, і всі відповіді були дуже інформативними!


Дякую Робін за чудову допомогу та інформацію. Якщо я можу запитати ще одну деталь: я десь натрапив на статтю, в якій сказано, що http-потоки також можуть кешуватися проксі-серверами, а веб-розетки - ні. що це означає?
Програмне забезпечення Гай

Оскільки StackOverflow обмежує розмір у коментарях до відповідей, я дав свою відповідь нижче: stackoverflow.com/questions/12555043/…
Robin Zimmermann

@RobinZimmermann, твоя відповідь - моя улюблена. +1 за дійсно гарну детальну відповідь.
securecurve

10

Якщо я можу запитати ще одну деталь: я десь натрапив на статтю, в якій сказано, що http-потоки також можуть кешуватися проксі-серверами, а веб-розетки - ні. що це означає?

(StackOverflow обмежує кількість відповідей на коментарі, тому мені довелося відповідати тут, а не вбудовувати.)

Це хороший момент. Щоб зрозуміти це, подумайте про традиційний сценарій HTTP ... Уявіть, що браузер відкрив веб-сторінку, тому він запитує http://example.com , скажімо. Сервер відповідає HTTP, який містить HTML сторінки. Тоді браузер бачить, що на сторінці є ресурси, тому він починає запитувати файли CSS, файли JavaScript і звичайно зображення. Це всі статичні файли, які будуть однаковими для всіх клієнтів, які їх запитують.

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

Тож клієнт №1 запитує http://example.com/images/logo.gif , скажімо. Цей запит проходить через проксі до центрального веб-сервера, який обслуговує logo.gif. Коли лого.gif проходить через проксі, проксі збереже це зображення і пов’яже його з адресою http://example.com/images/logo.gif .

Коли клієнт №2 приходить і запитує http://example.com/images/logo.gif , проксі може повернути зображення, і зв’язок не потрібен назад на веб-сервері в центрі. Це дає більш швидку відповідь кінцевому користувачеві, що завжди чудово, але це також означає, що на центр менше навантаження. Це може призвести до зниження витрат на обладнання, зменшення витрат на мережу тощо. Це добре.

Проблема виникає при оновленні logo.gif на веб-сервері. Проксі-сервер і надалі обслуговуватиме старе зображення, не знаючи, що є нове зображення. Це призводить до закінчення терміну дії, так що проксі буде кешувати зображення лише на короткий час, перш ніж воно "закінчиться", і наступний запит перейде через проксі на веб-сервер, який потім оновить кеш проксі. Є також більш вдосконалені рішення, де центральний сервер може висувати відомі кеші тощо, і все може вийти досить складним.

Як це стосується вашого питання?

Ви запитали про потоку HTTP, куди сервер передає HTTP клієнту. Але потокове передавання HTTP подібно до звичайного HTTP, за винятком того, що ви не перестаєте надсилати дані. Якщо веб-сервер обслуговує зображення, він надсилає HTTP клієнту, який врешті закінчується: ви надіслали все зображення. Якщо ви хочете надсилати дані, це точно так само, але сервер просто надсилає протягом дуже тривалого часу (як, скажімо, це масово-гігантське зображення, скажімо) або навіть ніколи не закінчується.

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

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

Так що це проблема.

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


1
відмінна подробиця Робін, велике спасибі! я дуже ціную вашу ретельну відповідь. я вже багато чого навчився від усіх чудових людей тут! :)
Програмне забезпечення Гай

4

HTTP обмежує кількість з'єднань, які може мати клієнт із сервером, до 2 (хоча це можна пом'якшити за допомогою піддоменів), і IE, як відомо, застосовує це з нетерпінням. Firefox та Chrome дозволяють отримати більше (хоча я не можу точно згадати, як саме було у верхній частині голови). Це може не здаватися великою проблемою, але якщо ви постійно використовуєте 1 з'єднання для оновлень у режимі реального часу, всі інші запити мають бути вузьким місцем через інше з'єднання HTTP. І справа в тому, що більш відкриті з'єднання від клієнтів приносять більше навантаження на сервер.

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


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