Paho C ++ asyn c клиентские обратные вызовы vs action_listener vs connected_handler - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь понять использование и поведение различных механизмов обратного вызова в библиотеке Paho MQTT C ++ при использовании async_client, а именно:

  • mqtt :: callback
  • mqtt :: iaction listener
  • mqtt :: connection_handler

Чего я добиваюсь: метод инициализации блокировки, который ожидает успешного подключения и успешной подписки к списку тем (одна топи c для начала), а также автоматизированные c повторное подключение и повторная подписка на эти темы в случае прекращения подключения.

Пример 'async_subscribe' (https://github.com/eclipse/paho.mqtt.cpp/blob/master/src/samples/async_subscribe.cpp) предлагает мне подписаться на темы в mqtt :: callback :: connected. Тем не менее, он не показывает, как ждать успешного завершения подписки. Насколько я понимаю, я не должен вызывать 'wait' на маркере подписки внутри подключенного обратного вызова. Если я установил частную переменную _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 Ответ

0 голосов
/ 01 апреля 2020

С дальнейшим изучением библиотек C ++ / C я смог убедиться, что Callback :: connected называется после Token :: on_success (и, следовательно, после того, как ожидание уже завершено).

Кажется, документы и образцы не очень хороши в этой области. Я поднял проблему в проекте Github: https://github.com/eclipse/paho.mqtt.cpp/issues/256.

Решением было:

  • Вызов подписки из обратного вызова on_success из соединения token (сначала убедитесь, что token_type == CONNECT)
  • В Callback :: connected, если причиной является "automati cconnect", я отправляю сообщение в основной поток, что нам нужно повторно подписаться на темы. Затем из основного потока я могу обработать переподключение (подписаться и дождаться завершения токенов подписки).
...