Создание простого HTTP-клиента с использованием Proxygen
8 июня 2022 г.Эта статья о proxygen — библиотеке, используемой для создания всех видов серверов. Он имеет открытый исходный код и поддерживается Meta. Изначально фреймворк задумывался как набор инструментов для разработки прокси. Следовательно, проксиген. Однако в этой библиотеке гораздо больше.
В первой статье этой серии мы рассмотрим разработку самого простого из возможных HTTP-клиентов. Здесь много движущихся частей, поэтому я предпочитаю сводить сложность к минимуму и сосредотачиваться только на том, что важно. Если вы читаете это, у вас, вероятно, есть голова на плечах, и вы сможете расширить это самостоятельно.
Во-первых, давайте начнем с очень общей архитектуры proxygen. Данные либо читаются из сокета, либо записываются в сокет. Затем у нас есть HTTPSession
, который использует HTTPCodec
для чтения/записи данных в/из сокета. Каждая HTTPSession
будет иметь одну или несколько HTTPTransactions
. Каждая HTTPTransaction
взаимодействует с обработчиком при получении/отправке данных. Вы можете увидеть это на изображении ниже.
Этот очень простой, но мощный набор абстракций позволяет обрабатывать все виды других протоколов, таких как HTTP2, HTTP3/QUIC/SPDY, включая собственные «домашние» протоколы. Но прежде чем вы начнете работать с любым из них, вы, вероятно, захотите создать самое простое приложение, чтобы убедиться, что проект настроен правильно и что вы понимаете все соответствующие концепции. Лично я считаю, что это самая сложная часть. Несмотря на то, что proxygen поставляется со своим собственным скриптом сборки и набором примеров, я не нашел его самым «дружественным». Porxygen в значительной степени зависит от некоторых других библиотек (например, folly, libevent, glog, gflags…), поэтому вам необходимо убедиться, что они также присутствуют в вашей системе. Вы также можете настроить используемый компилятор и/или компоновщик. Мне лично нравится использовать компилятор clang и набор инструментов, который идет с ним.
Чтобы помочь с вышеуказанными проблемами, я создал репозиторий, который делает следующее:
* вводит большинство зависимостей в виде подмодулей git * предоставляет скрипт сборки для сборки всех зависимостей * реализует простой HTTP-клиент (KissClient, Kiss означает keep it stupid simple) * содержит инструкции по сборке клиента
==Предостережение: в настоящее время проект работает только на Linux. На данный момент у меня нет планов заставить его работать на MacOS X или Windows. Сказав это, я готов принять запрос на вытягивание.==
Этого репозитория должно быть достаточно, чтобы вы могли создать свой собственный проект на его основе
проксиген.
== Если у вас возникнут какие-либо проблемы, откройте задачу (https://gitlab.com/ technologysoup/starter-kits/hello-proxygen/-/issues) или свяжитесь с нами через Discord (https://discord.gg/vFbZFzMmDK< /а>)==
Теперь давайте пройдемся по примеру. Я настоятельно рекомендую вам открыть код и ссылаться на него, пока вы читаете остальную часть. Код доступен в репозитории git:
https://gitlab.com/technologysoup/starter-kits/hello- proxygen/-/tree/main/src/kiss_client
KissClient
— это класс, в котором мы реализуем клиент. Он расширяет два других класса — proxygen::HTTPConnector::Callback
и proxygen::HTTPTransactionHandler
.
proxygen::HTTPConnector
используется для установления новых соединений HTTP или HTTPS, а proxygen::HTTPConnector::Callback
определяет объект обратного вызова, который будет получать результаты. Объект обратного вызова имеет методы connectSuccess
и connectError
.
HTTPTransaction
представляет одну пару запрос/ответ в HTTP-подобном протоколе. Он работает с транспортом и обработчиком для обработки входящих и исходящих данных.
Когда сеанс установлен, connectSuccess
вызывается с объектом сеанса, который, в свою очередь, используется для получения нового HTTPTransaction
. Этот объект транзакции (txn_
) используется для отправки заголовков и тела.
Как только клиент завершит отправку контента (заголовки + тело), сервер отправит ответ. В этот момент будут вызываться хуки, которые реализованы как часть интерфейса HTTPTransactionHandler
- onHeadersComplete
, onBody
, onEOM
, и т. д.
Подводя итог, последовательность событий такова:
- Приложение создает обратный вызов и объект обработчика.
- Затем приложение создает HTTPConnector, передавая ему обратный вызов и подключается к адресу.
- После успешного установления соединения с помощью перехватчиков обратного вызова создается HTTPSession.
- Сеанс используется для создания новой HTTP-транзакции. HTTPTransaction инициализируется с помощью объекта handler.
- Транзакция используется для отправки запроса на сервер.
- После получения ответа сервера вызываются перехватчики handler.
- Когда сеанс простаивает (это означает, что между клиентом и сервером больше нечего обменивать), сеанс закрывается.
И это все. У нас есть рабочий HTTP-клиент. Вы можете проверить это, запустив какой-нибудь сервер или используя netcat.
$ ./hello-proxygen
I0606 23:00:19.731132 1463353 kiss_client.cc:44] Sending request for http://localhost:4586
I0606 23:00:19.731266 1463353 kiss_client.cc:21] Got headers for http://localhost:4586.
I0606 23:00:19.731276 1463353 kiss_client.cc:24] Got body for http://localhost:4586.
I0606 23:00:19.731279 1463353 kiss_client.cc:31] Got EOM for http://localhost:4586.
В следующей статье я планирую показать, как сделать простой HTTP-сервер.
Если у вас есть какие-либо вопросы, не стесняйтесь оставлять комментарии ниже.
Оригинал