Как избежать обратного вызова ад с boost::beast?

Я работаю над приложением, в котором я хочу использовать boost::beast/asio. Мне нужно получать данные через соединение через веб-сокет и одновременно отправлять запросы в REST API.

В примерах асинхронного клиента boost::beast websocket/HTTP кажется, что следующая асинхронная операция запускается в обработчиках завершения. Кажется, это вызывает тот же "ад обратного вызова", который я видел в приложениях node.js.

Чтобы избежать этого, я думаю об использовании простого конечного автомата в моем приложении, чтобы решить, какую операцию запустить дальше. Я думаю о том, чтобы иметь цикл while в моем приложении, где я вызываю poll() для io_context, после чего я запускаю свой код конечного автомата (например, switch(state) { ... state = nextState; })

Однако это может создать занятый цикл, в котором основной поток потребляет 100% процессора, в то время как он постоянно запускает конечный автомат?

Верны ли мои рассуждения, и было бы лучше использовать что-то вроде post(), чтобы поставить в очередь функтор, который продвинет конечный автомат?

2 ответа

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

Если вы говорите о node.js, я предполагаю, что у вас есть некоторый опыт работы с "обещаниями" и / или более новым "async/await" - по крайней мере, именно так node.js избегает ада обратного вызова.

Оказывается, в Boost Asio есть что-то похожее на node.js 'async/await'. Он называется Boost Asio Coroutines, и вы реализуете его точно так же, как node.js 'async/await'.

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

В примерах асинхронного клиента boost::beast websocket/HTTP кажется, что следующая асинхронная операция запускается в обработчиках завершения

Существует множество различных примеров, которые поставляются с Beast, и каждый из них демонстрирует способ выполнения асинхронных операций, например, вот версия, которая использует стеки сопрограммы: https://github.com/boostorg/beast/blob/cfd9b460144a145f363c90533dc7c29dd1e1150d/example/websocket/server/coro/websocket_server_coro.cpp

Вот тот, который использует сопрограммы без стека: https://github.com/boostorg/beast/tree/cfd9b460144a145f363c90533dc7c29dd1e1150d/example/websocket/server/stackless

Вы не видели это? Все примеры описаны на этой странице в документации: https://www.boost.org/doc/libs/1_69_0/libs/beast/doc/html/beast/examples.html

Другие вопросы по тегам