путаница насчет двунаправленного и полнодуплексного в статьях про http / 2

Некоторые статьи, описывающие http / 2, хвалят его как двунаправленный, так и полнодуплексный.

AFAIK двунаправленный означает, что связь в обоих направлениях, поэтому дуплекс по своей природе двунаправленный, да?

Дуплекс может быть создан одним симплексным потоком, который переворачивается в некоторых определенных точках (полудуплекс), или он может быть создан как два противоположных симплексных потока (полнодуплексный).

Может быть, двунаправленный - это как инициировать обмен сообщениями? В http / 1 только клиент может инициировать отправку запроса на сервер, на который сервер возвращает ответ. В http / 2 сервер может отправить (протолкнуть) некоторый ресурс без явного запроса об этом. Но мы можем использовать Server-sent events в http / 1.1 (то есть сервер может отправлять сообщения, если он хочет, после небольшой настройки как на клиенте, так и на сервере, но это все еще по протоколу http / 1.1).

Подумав об этом, вы можете заметить, что http / 1 также является двунаправленным и полнодуплексным (поскольку конвейерная обработка в полудуплексе невозможна). Так что никаких изменений здесь с точки зрения http / 2.

Что изменилось, так это то, что http / 1 требовал, чтобы ответы приходили в точном порядке, в котором они были запрошены. http / 2 поднимает это с помощью потоков и мультиплексирования.


person marzelin    schedule 01.03.2019    source источник


Ответы (1)


Двунаправленный означает, что вы можете отправлять данные в обоих направлениях.

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

Если мы возьмем в качестве конечных точек «клиент» и «сервер» (независимо от того, сколько TCP-соединений между ними), то очевидно, что и HTTP / 1.1, и HTTP / 2 являются полнодуплексными.

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

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

Теперь мы можем перейти к вопросу незапрашиваемой связи от сервера к клиенту.

Это невозможно в HTTP / 1.1. Даже с Server Sent Events (SSE) клиент делает запрос, а сервер отвечает «бесконечным ответом», но клиент должен сделать запрос первым.

В HTTP / 1.1 SSE не является полнодуплексным с точки зрения одного TCP-соединения: сначала клиент делает запрос, а затем сервер отвечает «бесконечным ответом». С этого момента клиент может взаимодействовать с сервером только путем выполнения другого запроса, что означает открытие нового соединения.

В HTTP / 2 SSE является полнодуплексным, потому что клиент может связаться с сервером, сделав другой запрос в том же TCP-соединении, благодаря мультиплексированию HTTP / 2.

«Бесконечный ответ» SSE можно рассматривать как «сервер записывает блоки данных, которые можно интерпретировать как отправленные сообщения», но протокол SSE слишком прост, чтобы разрешать общие сообщения от сервера к клиенту (например, данные не могут быть двоичными). Вы не стали бы рассматривать загрузку, которая заикается, как сервер, отправляющий данные клиенту :)

Незапрашиваемая связь от сервера к клиенту также невозможна в HTTP / 2, поскольку HTTP / 2 может «протолкнуть» ресурс клиенту, но только в контексте предыдущего запроса.

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

Вот почему HTTP / 2 не может быть полной заменой протокола WebSocket, который является единственным веб-протоколом, который вы можете использовать для полной незапрашиваемой связи от сервера к клиенту.

person sbordet    schedule 01.03.2019
comment
Отличный ответ. Одно но: я бы не стал рассматривать веб-сокеты как 100% незапрошенную коммуникацию, поскольку она может быть установлена ​​только клиентом с запросом на обновление http. Если соединение установлено, у нас есть незапрашиваемая связь, но то же самое верно для http / 2 с SSE (одно TCP-соединение, обе стороны могут отправлять сообщения по своему желанию). - person marzelin; 01.03.2019
comment
@marzelin во всех протоколах, которые мы обсуждали, клиент устанавливает соединение. Я не рассматриваю установление соединения как часть определения двунаправленного, дуплексного или незапрашиваемого, потому что некоторая сторона должна начать коммуникацию. WebSocket устанавливает соединение, отправляя запрос HTTP / 1.1 (так что на этом этапе это еще не WebSocket). После этого запроса сервер отвечает HTTP 101, и после этого мы находимся в стране WebSocket, где клиент может быть просто пассивным, никогда ничего не отправлять на сервер и получать только незапрошенные сообщения с сервера. 1/2 - person sbordet; 01.03.2019
comment
Ни в одном из других протоколов вы не можете установить соединение и затем получить незапрошенное сообщение от сервера - клиент должен сначала отправить запрос. 2/2 - person sbordet; 01.03.2019
comment
да, все технологии, которые мы обсуждали, являются клиент-серверными. Для полноты я хотел бы упомянуть, что существует также WebRTC, который является одноранговым, где нет необходимости в явном разрешении от клиента для отправки или получения сообщений. - person marzelin; 01.03.2019