Как http-клиент связывает http-ответ с запросом (с Netty) или вообще?

Предполагается ли, что конечная точка http отвечает на запросы от конкретного клиента в порядке их получения?

Что делать, если это не имеет смысла в случае запросов, обрабатываемых кластером за прокси-сервером, или в запросах, обрабатываемых с помощью NIO, где один запрос выполняется быстрее, чем другой?

Существует ли стандартный способ связывания уникального идентификатора с каждым http-запросом для сопоставления с ответом? Как это обрабатывается в таких клиентах, как http-компоненты httpclient или curl?

Вопрос сводится к следующему случаю:

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


person MetaChrome    schedule 05.09.2011    source источник


Ответы (2)


Я не буду переписывать ответ CodeCaster, потому что он очень хорошо сформулирован.

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

Следует отметить, что существуют и другие протоколы, использующие аналогичный формат сообщений (в соответствии с RFC822). ), которые позволяют это сделать (используя такие механизмы, как заголовок cSeq SIP). ), и это можно было бы реализовать в пользовательском HTTP-приложении, но HTTP не определяет никакого стандартного механизма для этого, и поэтому нельзя сделать ничего, что можно было бы предположить, что оно будет работать везде. Это также создаст проблему с ответом на второе сообщение — вы ждете завершения первого ответа перед отправкой второго ответа или пытаетесь приостановить первый ответ, пока вы отправляете второй ответ? Как вы будете сообщать об этом таким образом, чтобы гарантировать, что сообщения не будут повреждены?

Также обратите внимание, что SIP (обычно) работает по протоколу UDP, который не гарантирует упорядоченность пакетов, что делает систему cSeq более необходимой.

Если вы хотите отправить запрос на сервер, пока другая транзакция все еще выполняется, вам нужно будет создать новое соединение с сервером и, следовательно, новый поток TCP.

Facebook провел некоторое исследование этого во время создания своей CDN и пришел к выводу, что вы можете эффективно иметь 2 или 3 открытых HTTP-потока в любой момент времени, но более того, это сокращает общее время передачи из-за дополнительных накладных расходов на пакеты. Я бы дал ссылку на запись в блоге, если бы мог найти ссылку ...

person DaveRandom    schedule 05.09.2011

Всякий раз, когда открывается TCP-соединение, оно распознается по исходному и целевому портам и IP-адресам. Поэтому, если я подключаюсь к www.google.com через целевой порт 80 (по умолчанию для HTTP), мне нужен свободный исходный порт, который сгенерирует ОС.

Затем ответ веб-сервера отправляется на исходный порт (и IP-адрес). Точно так же работает NAT, запоминая, какой исходный порт принадлежит какому внутреннему IP-адресу (и наоборот для входящих соединений).

Что касается вашего редактирования: нет, одно http-соединение может выполнять одну команду (GET/POST/etc) одновременно. Если вы отправляете другую команду во время извлечения данных из ранее введенной команды, результаты могут различаться в зависимости от реализации клиента и сервера. Я предполагаю, что Apache, например, будет передавать результат второго запроса после отправки данных первого запроса.

person CodeCaster    schedule 05.09.2011
comment
+1 - Хорошее краткое объяснение. Altoid Muncher, я думаю, вам стоит ознакомиться с некоторыми основами TCP, протокол транспортного уровня, на котором обычно работает HTTP. Программное обеспечение относительно высокого уровня, такое как веб-браузер или cURL, не должно беспокоиться об этом, оно обрабатывается базовым стеком TCP/IP операционной системы. Для дальнейшего чтения, тесно связанного с этим, как упоминал @CodeCaster, прочитайте NAT (преобразование сетевых адресов) - person DaveRandom; 05.09.2011
comment
+1 за хороший ответ. Предостережение: одно HTTP-соединение может выполнять несколько запросов при использовании HTTP Pipelining (вики: en.wikipedia.org/wiki/HTTP_pipelining, пример: info-chaitra.blogspot.com/2011/03/). Загвоздка в том, что запросы должны быть идемпотентными: допустимы GET, но не POST. - person Luca Invernizzi; 21.07.2012
comment
@LucaInvernizzi верно, но сервер не будет отправлять несколько ресурсов одновременно, это все еще FIFO: данные второго ответа будут отправлены после того, как все данные первого ответа будут отправлены. Нет мультиплексирования, как, например, в SPDY. О, и не говорите +1, когда вы не голосуете. ;-) - person CodeCaster; 21.07.2012