Есть много блогов и дискуссий о websocket и HTTP, и многие разработчики и сайты настоятельно рекомендуют websocket, но я до сих пор не могу понять, почему.
например (аргументы любителей websocket):
Веб-сокеты HTML5 представляют собой следующую эволюцию веб-коммуникаций - полнодуплексный, двунаправленный канал связи, который работает через один сокет в Интернете. ( 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 - https://en.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 для долговременных подключений все еще остаются.
Вопросы:
- Почему протокол веб-сокетов лучше?
- Почему это было реализовано вместо обновления протокола HTTP?
Ответы:
1) Почему протокол WebSockets лучше?
WebSockets лучше подходит для ситуаций, в которых используется коммуникация с малой задержкой, особенно с низкой задержкой для сообщений от клиента к серверу. Для данных от сервера к клиенту вы можете получить довольно низкую задержку, используя длительные соединения и частичную передачу. Однако, это не помогает с задержкой клиента к серверу, которая требует, чтобы новое соединение было установлено для каждого сообщения клиента к серверу.
Ваше 48-байтовое HTTP-рукопожатие нереально для реальных подключений через HTTP-браузер, где часто бывает несколько килобайт данных, отправленных как часть запроса (в обоих направлениях), включая множество заголовков и данных cookie. Вот пример запроса / ответа на использование Chrome:
Пример запроса (2800 байт, включая данные cookie, 490 байт без данных cookie):
Пример ответа (355 байт):
И HTTP, и WebSockets имеют начальные квитирования соединения одинакового размера, но при соединении WebSocket начальное квитирование выполняется один раз, а затем небольшие сообщения имеют только 6 байтов служебной информации (2 для заголовка и 4 для значения маски). Затраты на задержку не столько зависят от размера заголовков, сколько от логики для анализа / обработки / хранения этих заголовков. Кроме того, задержка установки TCP-соединения, вероятно, является более важным фактором, чем размер или время обработки для каждого запроса.
2) Почему это было реализовано вместо обновления протокола HTTP?
Предпринимаются усилия по реинжинирингу протокола HTTP для повышения производительности и снижения задержек, таких как SPDY , HTTP 2.0 и QUIC . Это улучшит ситуацию для обычных HTTP-запросов, но вполне вероятно, что WebSockets и / или WebRTC DataChannel будут по-прежнему иметь меньшую задержку при передаче данных между клиентами, чем протокол HTTP (или он будет использоваться в режиме, который очень похож на WebSockets). в любом случае).
Обновление :
Вот структура для размышлений о веб-протоколах:
text/event-stream
тип MIME. API браузера (который довольно похож на API WebSocket) называется API EventSource.Рекомендации :
источник
Вы, кажется, предполагаете, что WebSocket является заменой HTTP. Это не. Это расширение.
Основным вариантом использования WebSockets являются приложения Javascript, которые запускаются в веб-браузере и получают данные в режиме реального времени с сервера. Игры являются хорошим примером.
До появления WebSockets единственным способом взаимодействия приложений Javascript с сервером был сквозной
XmlHttpRequest
. Но у них есть главный недостаток: сервер не может отправлять данные, если клиент явно не запросил их.Но новая функция WebSocket позволяет серверу отправлять данные в любое время. Это позволяет реализовывать браузерные игры с гораздо меньшими задержками и без необходимости использовать уродливые хаки, такие как AJAX long-polling или плагины для браузера.
Так почему бы не использовать обычный HTTP с потоковыми запросами и ответами
В комментарии к другому ответу вы предложили просто асинхронно передавать поток запросов и ответов клиента.
На самом деле, WebSockets в основном так. Попытка открыть соединение WebSocket от клиента вначале выглядит как HTTP-запрос, но специальная директива в заголовке (Upgrade: websocket) говорит серверу начать связь в этом асинхронном режиме. Первые наброски протокола WebSocket не были чем-то большим, и потребовалось некоторое рукопожатие, чтобы убедиться, что сервер действительно понимает, что клиент хочет общаться асинхронно. Но затем стало понятно, что прокси-серверы будут смущены этим, потому что они привыкли к обычной модели HTTP запроса / ответа. Потенциальный сценарий атаки был обнаружен на прокси - сервера. Чтобы предотвратить это, необходимо было сделать трафик WebSocket не похожим на обычный HTTP-трафик. Вот почему маскирующие ключи были введены вокончательная версия протокола .
источник
Обычный API REST использует HTTP в качестве базового протокола для связи, которая следует парадигме запроса и ответа, что означает, что в сообщении участвует клиент, запрашивающий некоторые данные или ресурс с сервера, и сервер отвечает этому клиенту. Тем не менее, HTTP является протоколом без сохранения состояния, поэтому каждый цикл запрос-ответ в конечном итоге будет вынужден повторять информацию заголовка и метаданных. Это влечет за собой дополнительную задержку в случае часто повторяющихся циклов запрос-ответ.
В WebSockets, хотя связь по-прежнему начинается как первоначальное HTTP-рукопожатие, она дополнительно модернизируется, чтобы следовать протоколу WebSockets (т. Е. Если сервер и клиент совместимы с протоколом, поскольку не все объекты поддерживают протокол WebSockets).
Теперь с WebSockets можно установить полный дуплекс и постоянное соединение между клиентом и сервером. Это означает, что в отличие от запроса и ответа, соединение остается открытым до тех пор, пока приложение работает (т. Е. Оно постоянно), и, поскольку оно является дуплексным, возможна двусторонняя одновременная связь, т.е. теперь сервер способен инициировать сообщение и «проталкивают» некоторые данные клиенту, когда становятся доступными новые данные (которые интересуют клиента).
Протокол WebSockets с отслеживанием состояния и позволяет вам реализовать шаблон обмена сообщениями «Опубликовать-подписаться» (или «Опубликовать / подписать»), который является основной концепцией, используемой в технологиях реального времени, где вы можете получать новые обновления в виде push-уведомлений сервера без клиенту приходится запрашивать (обновлять страницу) повторно. Примерами таких приложений являются отслеживание местоположения автомобиля Uber, Push-уведомления, обновление цен на фондовом рынке в режиме реального времени, чат, многопользовательские игры, живые онлайн-инструменты для совместной работы и т. Д.
Вы можете прочесть статью о глубоких погружениях в Websockets, которая объясняет историю этого протокола, как он появился, для чего он используется и как вы можете реализовать его самостоятельно.
Вот видео из презентации, которую я сделал о WebSockets и о том, чем они отличаются от использования обычных API REST: Стандартизация и использование экспоненциального роста потоков данных
источник
Для TL; DR вот 2 цента и более простая версия для ваших вопросов:
WebSockets предоставляет следующие преимущества по сравнению с HTTP:
Протокол WebSocket и HTTP были разработаны для решения различных задач, IE WebSocket был разработан для улучшения двунаправленной связи, тогда как HTTP был разработан для того, чтобы не сохранять состояния и распространяться с использованием модели запроса / ответа. Помимо совместного использования портов по унаследованным причинам (проникновение через брандмауэр / прокси), не так много общего, чтобы объединить их в один протокол.
источник
Почему протокол веб-сокетов лучше?
Я не думаю, что мы можем сравнить их рядом, как кто лучше. Это не будет честным сравнением просто потому, что они решают две разные проблемы . Их требования разные. Это все равно что сравнивать яблоки с апельсинами. Они разные.
HTTP является протоколом запрос-ответ. Клиент (браузер) чего-то хочет, сервер дает. То есть. Если клиент данных хочет получить большие данные, сервер может отправить потоковые данные, чтобы избежать нежелательных проблем с буфером. Здесь основное требование или проблема заключается в том, как сделать запрос от клиентов и как ответить на ресурсы (гипертекст), которые они запрашивают. Вот где блеск HTTP.
WebSocket не является протоколом запрос-ответ, где только клиент может запросить. Это сокет (очень похож на сокет TCP). Имеется в виду, что после открытия соединения любая сторона может отправлять данные до тех пор, пока не будет закрыто подчеркивающее TCP-соединение. Это как обычная розетка. Единственное отличие от сокета TCP заключается в том, что websocket можно использовать в сети. В Интернете у нас есть много ограничений для обычного сокета. Большинство межсетевых экранов блокируют порты, отличные от 80 и 433, используемые HTTP. Прокси и посредники также будут проблематичными. Чтобы упростить развертывание протокола в существующих инфраструктурах, веб-сокет использует HTTP-рукопожатие для обновления. Это означает, что когда соединение открывается в первый раз, клиент отправляет HTTP-запрос, чтобы сообщить серверу: «Это не HTTP-запрос, пожалуйста, обновитесь до протокола websocket».
Когда сервер понял запрос и обновился до протокола websocket, ни один из протоколов HTTP больше не применяется.
Так что мой ответ: ни один не лучше друг друга. Они совершенно разные.
Почему это было реализовано вместо обновления протокола HTTP?
Ну, мы можем сделать все под именем HTTP . А мы будем? Если это две разные вещи, я предпочту два разных имени. Как и Хиксон и Майкл Картер .
источник
Другие ответы, кажется, не затрагивают ключевой аспект, и это то, что вы не упоминаете о необходимости поддержки веб-браузера в качестве клиента. Большинство ограничений простого HTTP выше предполагают, что вы будете работать с реализациями браузера / JS.
Протокол HTTP полностью поддерживает полнодуплексную связь; допустимо, чтобы клиент выполнял POST с передачей chunked-кодировки, а сервер возвращал ответ с телом chunked-encoding. Это позволит удалить заголовок только во время инициализации.
Поэтому, если вам нужен полный дуплекс, управление клиентом и сервером, и вы не заинтересованы в дополнительных кадрах / функциях веб-сокетов, то я бы сказал, что HTTP - более простой подход с более низкой задержкой / ЦП (хотя задержка будет действительно отличаться только микросекундами или меньше для обоих).
источник