I'm trying to understand the usage and behaviour of the various callback mechanisms in the Paho MQTT C++ library when using the async_client, specifically:
What I'm trying to achieve: A blocking initialise method that waits for successful connection and successful subscription to a list of topics (a single topic to begin with), plus automatic re-connection and re-subscription to those topics should the connection drop out.
The 'async_subscribe' sample (https://github.com/eclipse/paho.mqtt.cpp/blob/master/src/samples/async_subscribe.cpp) suggests I should subscribe to topics in mqtt::callback::connected. However, it does not show how to then wait for the subscription to successfully complete. My understanding is that I should not call 'wait' on the subscribe token inside the connected callback. If I set a private var _subscribeToken on which to wait, it seems there is no guarantee whether it has been set after waiting for the connect token to complete, i.e. (pseudo-code):
void Callback::connected(const std::string& cause){
_subscribeToken = _client->subscribe(topic, qos, nullptr, action_listener);
}
in initialise:
token_ptr connectToken = connect(connectOpts);
connectToken->wait();
_subscribeToken->wait(); // but _subscribeToken may still be null at this point.
What's the point of connectToken->wait if it doesn't guarantee the callback has been called yet? It's quite likely I'm misunderstanding something, but I'd like to be pointed in the right direction!
With some further digging into the C++/C libraries I was able to ascertain that Callback::connected is called after Token::on_success (and therefore after the wait has already completed).
It seems the docs and samples aren't great in this area. I've raised an issue in the Github project: https://github.com/eclipse/paho.mqtt.cpp/issues/256.
The solution was to: