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

222

Есть много блогов и обсуждений о 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?
  • 2
    Какой у Вас вопрос?
  • 0
    @Jonas, 1) почему протокол websockets лучше? 2) Почему это было реализовано вместо обновления протокола HTTP? 3) Почему веб-сокеты так продвигаются?
Показать ещё 5 комментариев
Теги:
http
websocket
comet

4 ответа

386

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.

Ссылки

  • 1
    >> Однако, это не помогает с задержкой клиента к серверу, которая требует нового соединения для каждого сообщения клиента к серверу. - как насчет потокового тела ответа? я знаю, API XMLHttpRequest не позволяет этого, но он существует. с потоковой передачей на сервер вы можете осуществлять потоковую передачу со стороны клиента.
  • 0
    @ 4esn0k, я не знаю ни одного способа сделать клиент-> сервер HTTP потоковым. Все решения, о которых я знаю, предназначены для потоковой передачи HTTP с сервера-> клиента. Маловероятно, что клиентское> серверное потоковое решение когда-либо будет принято или стандартизировано, потому что это нарушит семантику HTTP (даже потоковое сервер-клиент является сомнительным для многих). WebSockets - это решение, которое было разработано, чтобы обеспечить низкую задержку клиент-сервер (и, таким образом, в обоих направлениях) без соблюдения семантики HTTP.
Показать ещё 7 комментариев
100

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

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

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

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

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

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

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

  • 0
    >> Сервер не может отправлять данные, если клиент явно не запросил их .; Веб-браузер должен инициировать соединение WebSockets ... так же, как для XMLHttpRequest
  • 16
    @ 4esn0k Браузер инициирует соединение через веб-сокет. Но после того, как это установлено, обе стороны могут отправлять данные в любое время. Это не относится к XmlHttpRequest.
Показать ещё 4 комментария
14

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

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

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

  • 2
    Важно то, что вы упомянули термин «без учета состояния и без учета состояния» в своем сравнении (Y)
2

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню