Протокол WebSockets vs HTTP

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

например (аргументы любителей websocket):

HTML5 Web Sockets представляет собой следующую эволюцию веб-коммуникаций - полнодуплексный, двунаправленный канал связи, который работает через один сокет через Интернет.   (http://www.websocket.org/quantum.html)

HTTP поддерживает потоковое вещание: потоковое вещание запроса (вы используете его при загрузке больших файлов) и потоковое тело ответа.

Во время соединения с WebSocket клиент и сервер обмениваются данными на каждый кадр, который по 2 байта, по сравнению с 8 килобайтами заголовка http при непрерывном опросе.

Почему эти 2 байта не включают в себя tcp и под потоки протоколов tcp?

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

Это HTTP-заголовок ~ 48 байтов.

http chunked encoding - http://ru.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 с подключением с длительным подключением все еще существуют.

Вопрос:

  • Почему протокол websockets лучше?
  • Почему это было реализовано вместо обновления протокола HTTP?

Ответ 1

1) Почему протокол WebSockets лучше?

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

Ваше 48-байтовое HTTP-соединение не реалистично для реальных 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-потоковая передача: множество методов (multipart/chunked response), которые позволяют серверу отправлять более одного ответа на один клиентский запрос. W3C стандартизирует это как Server-Sent Events с использованием типа text/event-stream MIME. API-интерфейс браузера (который довольно похож на API WebSocket) называется API-интерфейсом EventSource.
  • Комета/сервер push: это зонтичный термин, который включает в себя как потоковое голосование, так и потоковое HTTP. Библиотеки комет обычно поддерживают несколько методов, чтобы попытаться максимизировать поддержку кросс-браузера и кросс-сервера.
  • WebSockets: транспортный уровень, встроенный в TCP, который использует HTTP-приветствие. В отличие от TCP, который является потоковым транспортом, WebSockets представляет собой транспорт на основе сообщений: сообщения разделяются на проводе и повторно собираются полностью до доставки в приложение. Соединения WebSocket двунаправленные, полнодуплексные и долгоживущие. После первоначального запроса/ответа на рукопожатие нет транзакционной семантики, и для каждого сообщения слишком мало. Клиент и сервер могут отправлять сообщения в любое время и должны обрабатывать получение сообщения асинхронно.
  • SPDY: предложение, инициированное Google, расширить HTTP-протокол, используя более эффективный проводной протокол, но поддерживающий всю семантику HTTP (запрос/ответ, файлы cookie, кодирование). SPDY вводит новый формат кадрирования (с кадрами с префиксом длины) и задает способ расслоения пар HTTP-запросов/ответов на новый уровень кадрирования. Заголовки могут быть сжаты и новые заголовки могут быть отправлены после установления соединения. Существуют реалистичные реализации SPDY в браузерах и серверах.
  • HTTP 2.0: имеет схожие задачи с SPDY: уменьшает задержку HTTP и накладные расходы при сохранении семантики HTTP. Текущий проект получен из SPDY и определяет рукопожатие обновления и кадрирование данных, которое очень похоже на стандарт WebSocket для установления связи и кадрирования. Альтернативное проектное предложение HTTP 2.0 (httpbis-speed-mobility) фактически использует WebSockets для транспортного уровня и добавляет мультиплексирование SPDY и сопоставление HTTP как расширение WebSocket (расширения WebSocket согласовываются во время рукопожатия).
  • WebRTC/CU-WebRTC: предложения для обеспечения возможности одноранговой связи между браузерами. Это может обеспечить более низкую среднюю и максимальную задержку связи, поскольку в качестве основного транспорта используется SDP/датаграмма, а не TCP. Это позволяет не доставлять пакеты пакетов/сообщений, которые позволяют избежать проблем с шифрованием задержки, вызванных потерянными пакетами, которые задерживают доставку всех последующих пакетов (чтобы гарантировать доставку в порядке).
  • QUIC: является экспериментальным протоколом, направленным на снижение латентности сети по сравнению с TCP. На поверхности QUIC очень похож на TCP + TLS + SPDY, реализованный в UDP. QUIC обеспечивает мультиплексирование и управление потоком, эквивалентное HTTP/2, эквивалент безопасности, эквивалентный TLS, а также семантику, надежность и контроль перегрузки, эквивалентную TCP. Поскольку TCP реализован в ядрах операционной системы и прошивке промежуточных программ, существенные изменения в TCP практически невозможны. Однако, поскольку QUIC построен поверх UDP, он не имеет таких ограничений. QUIC спроектирован и оптимизирован для семантики HTTP/2.

Ссылки

Ответ 2

Предполагается, что WebSocket заменяет HTTP. Это не. Это расширение.

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

Прежде чем WebSockets, единственный способ использования Javascript-приложений для взаимодействия с сервером - через XmlHttpRequest. Но у них есть главный недостаток: сервер не может отправлять данные, если клиент явно не запросил его.

Но новая функция WebSocket позволяет серверу отправлять данные всякий раз, когда захочет. Это позволяет реализовать браузерные игры с гораздо более низкой задержкой и без необходимости использовать уродливые хаки, такие как AJAX для долгого опроса или плагинов браузера.

Итак, почему бы не использовать обычный HTTP с потоковыми запросами и ответами

В комментарии к другому ответу вы предложили просто передать клиентский запрос и тело ответа асинхронно.

Фактически, WebSockets в основном таковы. Попытка открыть соединение с WebSocket с клиентом сначала выглядит как HTTP-запрос, но специальная директива в заголовке (Upgrade: websocket) сообщает серверу начать общение в этом асинхронном режиме. Первые черновики протокола WebSocket были не намного больше, чем некоторые, и некоторые подтверждения, чтобы убедиться, что сервер действительно понимает, что клиент хочет общаться асинхронно. Но тогда было осознано, что прокси-серверы будут смущены этим, потому что они используются для обычной модели запроса/ответа HTTP. Был обнаружен потенциальный сценарий атаки на прокси-серверы. Чтобы этого избежать, необходимо было заставить трафик WebSocket выглядеть в отличие от любого обычного HTTP-трафика. Вот почему маскирующие клавиши были введены в окончательную версию протокола.

Ответ 3

Для TL; DR, здесь 2 цента и более простая версия для ваших вопросов:

  • WebSockets предоставляет эти преимущества по HTTP:

    • Постоянное соединение с состоянием на время соединения
    • Низкая латентность: почти в режиме реального времени связь между сервером/клиентом из-за отсутствия накладных расходов на восстановление соединений для каждого запроса по требованию HTTP.
    • Полный дуплекс: оба сервера и клиент могут отправлять/получать одновременно
  • Протокол WebSocket и HTTP был разработан для решения различных задач, I.E. WebSocket был разработан для улучшения двунаправленной связи, в то время как HTTP был разработан как безгражданный, распределенный с использованием модели запроса/ответа. Помимо совместного использования портов по устаревшим причинам (проникновение через брандмауэр/прокси), не так много общего, чтобы объединить их в один протокол.

Ответ 4

Почему протокол веб-сокетов лучше?

Я не думаю, что мы можем сравнить их рядом, кто лучше. Это не будет честным сравнением просто потому, что они решают две разные проблемы. Их требования разные. Это все равно что сравнивать яблоки с апельсинами. Они разные.

HTTP является протоколом запрос-ответ. Клиент (браузер) чего-то хочет, сервер - это. Это. Если клиент данных хочет получить большие данные, сервер может отправить потоковые данные, чтобы избежать нежелательных проблем с буфером. Здесь основное требование или проблема заключается в том, как сделать запрос от клиентов и как ответить на ресурсы (гипертекст), которые они запрашивают. Вот где блеск HTTP.

В HTTP только клиентский запрос. Сервер только отвечает.

WebSocket не является протоколом запрос-ответ, где только клиент может запросить. Это сокет (очень похож на сокет TCP). Имеется в виду, что после открытия соединения любая сторона может отправлять данные до тех пор, пока не будет закрыто подчеркивающее TCP-соединение. Это как обычная розетка. Единственное отличие от сокета TCP заключается в том, что websocket можно использовать в сети. В Интернете у нас есть много ограничений для обычного сокета. Большинство межсетевых экранов блокируют порты, отличные от 80 и 433, используемые HTTP. Прокси и посредники также будут проблематичными. Чтобы упростить развертывание протокола в существующих инфраструктурах, веб-сокет использует HTTP-рукопожатие для обновления. Это означает, что когда соединение открывается в первый раз, клиент отправляет HTTP-запрос, чтобы сообщить серверу: "Это не HTTP-запрос, пожалуйста, обновитесь до протокола websocket".

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

Как только сервер поймет запрос и перейдет на протокол веб-сокета, протокол HTTP больше не будет применяться.

Так что мой ответ Ни один из них не лучше, чем друг друга. Они совершенно разные.

Почему это было реализовано вместо обновления протокола HTTP?

Ну, мы можем сделать все под именем HTTP. А мы будем? Если это две разные вещи, я предпочту два разных имени. Как и Хиксон, и Майкл Картер.

Ответ 5

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

http

В WebSockets, хотя связь по-прежнему начинается как первоначальное HTTP-рукопожатие, она дополнительно модернизируется, чтобы следовать протоколу WebSockets (т.е. если сервер и клиент совместимы с протоколом, поскольку не все объекты поддерживают протокол WebSockets).

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

websockets

Протокол WebSockets с отслеживанием состояния и позволяет вам реализовать шаблон обмена сообщениями "Публикация-подписка (или публикация/подписка)", который является основной концепцией, используемой в технологиях реального времени, где вы можете получать новые обновления в форме push-сообщений сервера без клиенту приходится запрашивать (обновлять страницу) повторно. Примерами таких приложений являются отслеживание местоположения автомобилей Uber, Push-уведомления, обновление цен на фондовом рынке в режиме реального времени, чат, многопользовательские игры, инструменты для совместной работы в режиме онлайн и т.д.

Вы можете ознакомиться с подробной статьей о Websockets, в которой рассказывается об истории этого протокола, о том, как он появился, для чего он используется и как вы можете реализовать его самостоятельно.

Вот видео из презентации, которую я сделал о WebSockets и о том, чем они отличаются от обычных API REST: Стандартизация и использование экспоненциального роста потоковой передачи данных

Ответ 6

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

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

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