Мое понимание HTTP-опроса, длинного опроса, потоковой передачи HTTP и веб-узлов

Я прочитал много сообщений о SO и в Интернете относительно ключевых слов в моем заголовке вопроса и многому научился у них. Некоторые из вопросов, которые я читаю, связаны с конкретными задачами реализации, в то время как другие сосредоточены на общих концепциях. Я просто хочу удостовериться, что я понял все концепции и рассуждения о том, почему технология X была изобретена по технологии Y и так далее. Итак, вот:

Опрос Http: В основном AJAX, используя XmlHttpRequest.

Http Long Polling: AJAX, но сервер держит ответ, если у сервера нет обновления, как только сервер получит обновление, он отправит его, а затем клиент может отправить другой запрос, Недостаток - это дополнительные данные заголовка, которые необходимо отправлять назад и вперед, вызывая дополнительные накладные расходы.

Http Streaming:. Подобно длинному опросу, но сервер отвечает заголовком "Transfer Encoding: chunked", и поэтому нам не нужно инициировать новый запрос каждый раз, когда сервер отправляет некоторые данные ( и, следовательно, сохранить дополнительные служебные данные заголовка). Недостатком здесь является то, что мы должны "понять" и выяснить структуру данных, чтобы различать несколько кусков, отправленных сервером.

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

WebSockets: это новый API, который пытается устранить короткие приемы описанных выше методов следующим образом:

  • Единственное преимущество WebSockets над плагинами, такими как Java-апплеты, Flash или Silverlight, заключается в том, что WebSockets встроены в браузеры и не полагаются на плагины.
  • Единственное преимущество WebSockets над потоком HTTP заключается в том, что вам не нужно прилагать усилия, чтобы "понять" и проанализировать полученные данные.
  • Единственным преимуществом WebSockets для Long Polling является исключение дополнительного размера заголовков и открытие и закрытие соединения сокетов для запроса.

Есть ли другие существенные отличия, которые мне не хватает? Прошу прощения, если я повторно задаю или объединю многие вопросы, уже находящиеся на SO, в один вопрос, но я просто хочу получить полное представление обо всей информации, которая находится там в SO и в Интернете, в отношении этих понятий.

Спасибо!

Ответ 1

Есть больше различий, чем те, которые вы определили.

Duplex/Направленный:

  • Uni-directional: HTTP-опрос, длительный опрос, потоковая передача.
  • Bi-directcitonal: WebSockets, плагиновая сеть.

В порядке увеличения задержки (приблизительный):

  • WebSockets
  • Сетевые подключения
  • Потоковая передача HTTP
  • HTTP long-poll
  • HTTP-опрос

CORS (поддержка кросс-оригинала):

  • WebSockets: yes
  • Сетевые подключения: Flash через запрос политики (не уверен в других)
  • HTTP * (недавняя поддержка)

Нативные двоичные данные (типизированные массивы, капли):

  • WebSockets: yes
  • Сетевые подключения: не с Flash (требуется кодировка URL-адресов через ExternalInterface)
  • HTTP *: недавнее предложение включить поддержку двоичного типа.

Полоса пропускания при снижении эффективности:

  • Сетевые подключения: флэш-сокеты являются исходными, за исключением исходного запроса политики
  • WebSockets: подключение к настройке соединения и несколько байтов на кадр
  • Потоковая передача HTTP (повторное использование подключения к серверу)
  • HTTP long-poll: подключение для каждого сообщения
  • HTTP-опрос: соединение для каждого сообщения + сообщения с данными

Поддержка мобильных устройств:

  • WebSocket: iOS 4.2 и выше. Некоторые Android с помощью эмуляции Flash или с помощью Firefox для Android или Google Chrome для Android, которые предоставляют встроенную поддержку WebSocket.
  • Плагин сети: некоторые Android. Не на iOS
  • HTTP *: в основном да

Сложность использования Javascript (от простейшего до самого сложного). Понятно, что меры сложности несколько субъективны.

  • WebSockets
  • Опрос HTTP
  • Сетевые подключения
  • HTTP long poll, streaming

Также обратите внимание, что есть предложение W3C для стандартизации потоковой передачи HTTP, называемое Server-Sent Events. В настоящее время он довольно рано развивается и предназначен для предоставления стандартного API Javascript с сопоставимой простотой в WebSockets.

Ответ 2

Некоторые отличные ответы от других, которые покрывают много земли. Здесь немного больше.

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

Если вы подразумеваете, что вы можете использовать Java-апплеты, 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, тем самым расширяя этот серверный сервер до Web. Часто существующее приложение, которое было заблокировано на предприятии, может расширить его доступ с помощью WebSocket без необходимости изменения какой-либо внутренней инфраструктуры.

(Естественно, вы захотите сделать все это надежно, поэтому обратитесь к поставщику или поставщику WebSocket.)

Некоторые люди ссылаются на WebSocket как TCP для Интернета. Так как TCP транслирует протоколы более высокого уровня, WebSocket так же совместим с веб-инфраструктурой.

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

Прошу прощения, если я повторно задаю или объединю многие из вопросов, которые уже находятся на SO, в один вопрос, но я просто хочу понять, какая информация находится там в SO и в Интернете относительно эти понятия.

Это был отличный вопрос, и ответы были очень информативными!

Ответ 3

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

(StackOverflow ограничивает размер комментариев комментариев, поэтому мне пришлось отвечать здесь, а не в строке.)

Это хороший момент. Чтобы понять это, подумайте о традиционном сценарии HTTP... Представьте, что браузер открыл веб-страницу, поэтому он запрашивает http://example.com. Сервер отвечает HTTP, который содержит HTML для страницы. Затем браузер видит, что на странице есть ресурсы, поэтому он начинает запрашивать файлы CSS, файлы JavaScript и изображения, конечно. Это все статические файлы, которые будут одинаковыми для всех клиентов, запрашивающих их.

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

Таким образом, клиент # 1 запрашивает http://example.com/images/logo.gif, скажем. Этот запрос проходит через прокси-сервер до центрального веб-сервера, который обслуживает logo.gif. Поскольку logo.gif проходит через прокси, прокси сохраняет это изображение и связывает его с адресом http://example.com/images/logo.gif.

Когда клиент № 2 приходит, а также запрашивает http://example.com/images/logo.gif, прокси-сервер может вернуть изображение, и связь не требуется обратно в Интернет сервер в центре. Это дает более быстрый ответ конечному пользователю, который всегда велик, но это также означает, что на центр меньше нагрузки. Это может привести к сокращению затрат на оборудование, снижению сетевых затрат и т.д. Так что это хорошо.

Проблема возникает, когда logo.gif обновляется на веб-сервере. Прокси-сервер будет продолжать обслуживать старый образ, не осознавая, что есть новое изображение. Это приводит к тому, что прокси-сервер будет кэшировать изображение только за короткое время до истечения срока его действия, а следующий запрос проходит через прокси-сервер к веб-серверу, который затем обновляет кеш-прокси. Существуют также более продвинутые решения, в которых центральный сервер может выходить в известные кэши и т.д., И все может стать довольно сложным.

Как это связано с вашим вопросом?

Вы спросили о потоковой передаче HTTP, где сервер передает HTTP клиенту. Но потоковая передача HTTP - это как обычный HTTP, за исключением того, что вы не прекращаете отправку данных. Если веб-сервер обслуживает изображение, он отправляет HTTP клиенту, который в конечном итоге заканчивается: вы отправили все изображение. И если вы хотите отправить данные, это точно так же, но сервер просто отправляет на очень долгое время (например, это гигантский гигантский образ, скажем) или даже никогда не заканчивается.

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

Итак, если ваш клиент запросил цены акций, скажем, и получил ответ, то следующий клиент может сделать тот же запрос и получить кэшированные данные. Наверное, не то, что вы хотите! Если вы запрашиваете цены на акции, вы хотите получить последние данные, верно?

Так что это проблема.

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

Ответ 4

HTTP ограничивает количество подключений, которые клиент может иметь с сервером до 2 (хотя это можно смягчить с помощью поддоменов), и, как известно, IE защищает это с нетерпением. Firefox и Chrome позволяют больше (хотя я точно не помню, насколько много). Это может показаться не огромной проблемой, но если вы используете одно подключение постоянно для обновлений в реальном времени, все остальные запросы должны быть узким местом через другое HTTP-соединение. И есть вопрос, что больше открытых подключений от клиентов ставит большую нагрузку на сервер.

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