Обратные вызовы асинхронного клиента Paho C++ против action_listener против connected_handler
Я пытаюсь понять использование и поведение различных механизмов обратного вызова в библиотеке Paho MQTT C++ при использовании async_client, а именно:
- mqtt::callback
- mqtt:: iaction слушатель
- mqtt::connection_handler
Чего я пытаюсь достичь: метод инициализации блокировки, ожидающий успешного подключения и успешной подписки на список тем (для начала - одна тема), а также автоматическое повторное подключение и повторная подписка на эти темы в случае разрыва соединения вне.
Пример async_subscribe (https://github.com/eclipse/paho.mqtt.cpp/blob/master/src/samples/async_subscribe.cpp) предлагает подписаться на темы в mqtt::callback::connected. Однако он не показывает, как затем дождаться успешного завершения подписки. Насколько я понимаю, я не должен вызывать "ждать" токена подписки внутри связанного обратного вызова. Если я устанавливаю частный var _subscribeToken для ожидания, похоже, нет гарантии, был ли он установлен после ожидания завершения токена подключения, то есть (псевдокод):
void Callback::connected(const std::string& cause){
_subscribeToken = _client->subscribe(topic, qos, nullptr, action_listener);
}
в инициализации:
token_ptr connectToken = connect(connectOpts);
connectToken->wait();
_subscribeToken->wait(); // but _subscribeToken may still be null at this point.
Какой смысл connectToken-> ждать, если он еще не гарантирует, что обратный вызов еще был вызван? Вполне вероятно, что я что-то недопонимаю, но мне бы хотелось, чтобы меня указали в правильном направлении!
1 ответ
После дальнейшего изучения библиотек C++/C я смог убедиться, что Callback::connected вызывается после Token::on_success (и, следовательно, после того, как ожидание уже завершилось).
Кажется, что документы и образцы не очень хороши в этой области. Я поднял проблему в проекте Github: https://github.com/eclipse/paho.mqtt.cpp/issues/256.
Решение было:
- Вызов подписки из обратного вызова on_success из токена подключения (сначала убедитесь, что token_type == CONNECT)
- В Callback::connected, если причиной является "автоматическое переподключение", я отправляю сообщение обратно в основной поток, в котором нам нужно повторно подписаться на темы. Затем из основного потока я могу обработать повторное подключение (подписаться и дождаться завершения токенов подписки).