Привет, читатель блога ZametkiNaPolyah.ru! Продолжим знакомиться с протоколом HTTP в рубрике серверы и протоколы и ее разделе HTTP протокол. В данной записи мы с тобой поговорим про HTTP соединения и, в основном, о том, как они реализованы в HTTP протоколе версии 1.1. Для начала скажу, что на данный момент действуют постоянные HTTP соединения, это означает одну простую вещь: за одну TCP сессию можно отправить несколько HTTP запросов и получить столько же HTTP ответов, раньше это было далеко не так. Так же в этой записи мы затронем требования к передаче HTTP сообщений.
HTTP соединение (HTTP Connections)
Постоянные HTTP соединения (Persistent Connections HTTP)
Если вы хотите узнать всё про протокол HTTP, обратитесь к навигации по рубрике HTTP протокол. HTTP соединение или HTTP Connections на данный момент является постоянным для каждого URL (читай про URI в HTTP), когда-то давно для каждого запроса клиента использовалось отдельное TCP соединение (даже если страница просто обновлялась), что создавало большую нагрузку на машины с HTTP серверами, потому что каждый элемент страницы, например изображение – это один или несколько запросов от клиента к серверу.
Давайте посмотрим, что дают постоянные HTTP соединения (HTTP Connections):
- Сейчас не требуется постоянно поднимать новое TCP соединение для запроса, поэтому существенно экономятся ресурсы серверов.
- HTTP запросы клиента и ответы сервера можно представить как непрерывно работающий конвейер, причем параллельный, в рамках одного TCP соединения.
- Для установки TCP соединения машине клиента и машине сервера обязательно нужно посылать пакеты, следовательно, третий уровень модели OSI был очень загружен, так было до появления постоянного HTTP соединения (HTTP Connections).
Поэтому на данный момент все HTTP клиенты и HTTP серверы разрабатываются с учетом того, чтобы работать, используя постоянные HTTP соединения между клиентом и сервером. В версии протокола HTTP 1.1 любой клиент по умолчанию считает, что ему нужно работать с сервером по постоянному HTTP соединению (Persistent Connection HTTP). Как только клиент и сервер прекратили общаться, им необходимо разорвать TCP соединение, делается это специальным полем в заголовке Connection (если не знаете, что такое заголовки и поля, то почитайте статью параметры HTTP). После того, как клиент получил сообщение о разрыве TCP соединения, он не должен (читай про требования HTTP) посылать серверу заголовки.
С учетом того, что HTTP соединение постоянное, клиент может посылать несколько HTTP запросов подряд, не ожидаю HTTP сообщений от сервера, но сервер должен посылать HTTP ответы на сообщения клиента в том порядке, в котором он получил запросы. С учетом того, что на данный момент используется постоянное HTTP соединение (HTTP Connections), сервера имеют определенные значения времени ожидания (конкретные цифры зависят непосредственно от настроек сервера), после которого они перестают поддерживать неактивные соединения.
Хочу заметить, что при закрытии TCP соединения клиент и сервер могут работать асинхронно (хотя HTTP протокол по всем определениям синхронный). Например, мы имеем неактивное HTTP соединение, у сервера закончилось время ожидания, и он отправляет клиенту сообщение о том, что он рвет TCP соединение, но в это же самое время клиент отправляет какой-то HTTP запрос, в этом случае программа клиента должна «справиться» без участия человека, а именно: отправить запрос на установку нового HTTP соединения и повторить предыдущий запрос.
В общем, суть данного поста в том, что на данный момент в HTTP поддерживается конвейерное постоянное HTTP соединение с возможностью асинхронной обработки события закрытия соединения.
Требования к передаче сообщений и выбор HTTP соединений (HTTP Connections)
Общие требования к передаче сообщений в стандарте HTTP:
- В HTTP 1.1 серверам следует поддерживать постоянные HTTP соединения.
- В HTTP1 клиентам следует во время отправки сообщения контролировать соединение на предмет ошибок. При обнаружении ошибки клиенту следует немедленно прекратить передачу. Если тело HTTP сообщения посылается с использованием кодирования по кускам, то кусок нулевой длины могут использоваться для индикации преждевременного конца сообщения.
- Протокол HTTP версии 1.1 предусматривает то, что клиент должен уметь работать с кодом состояния 100.
Сервера версии HTTP 1.1 должны уметь работать с клиентами 1.0 и ниже, при этом сервера не должны использовать сообщения с кодом состояния 100. Если клиент HTTP 1.1 взаимодействует с сервером 1.0 , то для корректной отправки повторного запроса он должен использовать следующий алгоритм:
- Инициализировать новое соединение с сервером.
- Передать заголовки запроса (request-headers).
- Инициализировать переменную R примерным временем передачи информации на сервер и обратно (например на основании времени установления соединения), или постоянным значение в 5 секунд, если время передачи не доступно.
- Вычислить T = R * (2**N), где N — число предыдущих повторов этого запроса.
- Либо дождаться от сервера ответа с кодом ошибки, либо просто выждать T секунд (смотря что произойдет раньше).
- Если ответа с кодом ошибки не получено, после T секунд передать тело запроса.
- Если клиент обнаруживает, что HTTP соединение было закрыто преждевременно, то ему нужно повторять начиная с шага 1, пока запрос не будет принят, либо пока не будет получен ошибочный ответ, либо пока у пользователя не кончится терпение и он не завершит процесс повторения.
Вот такие требования к передаче HTTP сообщений предъявляются стандартом HTTP. На этом мы закончим рассмотрение HTTP соединений, более полную информацию вы сможете узнать из стандарта HTTP 1.1.
Выберете удобный для себя способ, чтобы оставить комментарий