Использовать указатель клиента MQTT среди функций C++

Я использую библиотеку Paho C++ MQTT для подключения к моему брокеру.

Я хочу, чтобы мой код был организован следующим образом:

connect();
sendMessage(data);
disconnect();

Мне уже удалось подключиться, отправить сообщение и отключиться, но только в той же функции из-за области действия клиента MQTT:

void sendMessage(){
    // Connect
    mqtt::itoken_ptr conntok = client.connect();
    conntok->wait_for_completion();

    // Sending message
    pubtok = client.publish(topic, char_json, data, qos, false);
    pubtok->wait_for_completion(timeout);

    // Disconnect
    conntok = client.disconnect();
    conntok->wait_for_completion();
}

Однако я хочу иметь эти фрагменты кода в трех отдельных функциях (чтобы избежать повторного подключения/отключения каждый раз, когда я отправляю некоторые данные)

Я предполагаю, что мне нужно использовать mqtt::itoken_ptr conntok, который возвращается из client.connect(), но этот объект не имеет get_client()< /strong> работает только mqtt:token.

Документация показывает, что существует указатель на класс async_client std::shared_ptr ptr_t, но я не уверен, как его использовать, так как я новичок в C++. Фактический клиентский объект является закрытым (под оболочкой C++).

Как я могу использовать один и тот же клиентский объект в разных функциях, чтобы иметь следующее?

connect(){
   mqtt::itoken_ptr conntok = client.connect();
}
sendMessage(){
   pubtok = client.publish(topic, char_json, data, qos, false);
   pubtok->wait_for_completion(timeout);
}
disconnect(){
   conntok = client.disconnect();
   conntok->wait_for_completion();
}

person mrlenbenquet    schedule 06.11.2016    source источник
comment
Вот более подробная документация по std::shared_ptr.   -  person πάντα ῥεῖ    schedule 06.11.2016
comment
Спасибо. Я читал эту документацию, но не мог понять, как получить клиент. Я не могу вернуть itoken_ptr (поскольку он абстрактный) и не могу вернуть mqtt:iasync_client, возвращаемый conntok.get()->get_client();   -  person mrlenbenquet    schedule 06.11.2016
comment
Вот что я пробовал: std::shared_ptr<mqtt::itoken>connectTo(); возвращает smart_ptr в мою основную функцию. bool disconnectFrom(std::shared_ptr<mqtt::itoken>token) использует этот токен для отключения с помощью: token->get_client()->disconnect(); Я не получаю ошибок во время компиляции, но получаю ошибку сегментации при попытке отключения. Я предполагаю, что это потому, что этот токен больше не связан с клиентом, поэтому указатель никуда не ведет.   -  person mrlenbenquet    schedule 06.11.2016
comment
Токены связаны с транзакцией, для которой они созданы — не думайте, что это то, чем вы хотите поделиться. «клиент» — это то, чем нужно делиться. Вам нужен где-то объект контроллера, который создает клиента и передает его методам sendMessage и разъединения.   -  person barny    schedule 08.11.2016
comment
Вот и я так же подумал. Однако у токенов есть метод get_client(), который возвращает клиента, но я не могу вернуть клиента, а затем использовать client.anyMethod() без получения ошибки ошибки сегментации.   -  person mrlenbenquet    schedule 10.11.2016


Ответы (1)


Не проверял это, но почему вы не можете в псевдокоде:

void disconnect(mqtt::iasync_client &client);
void connect(mqtt::iasync_client &client);
void sendMessage(mqtt::iasync_client &client);

controller()
{
   mqtt::async_client client(ADDRESS, CLIENTID);
   connect(client);
   sendMessage(client);
   disconnect(client);
}

connect(&client){
   callback cb;
   client.set_callback(cb); // necessary to avoid segmentation fault
   token = client.connect();
   token->wait_for_completion(timeout);
}

sendMessage(&client){
   callback cb;
   client.set_callback(cb); // necessary to avoid segmentation fault
   pubtok = client.publish(topic, char_json, data, qos, false);
   pubtok->wait_for_completion(timeout);
}

disconnect(&client){
   callback cb;
   client.set_callback(cb);
   conntok = client.disconnect();
   conntok->wait_for_completion();
}
person barny    schedule 08.11.2016
comment
Ваш пост заставил меня понять, что я неправильно передал клиента в качестве параметра. Я использовал ваш псевдокод, и теперь он работает. Мне пришлось передать клиента по ссылке, например: connectTo(mqtt::iasync_client& client). - person mrlenbenquet; 10.11.2016
comment
Честно говоря, я все еще не на 100% доволен этим решением; эти мои данные отправляются в цикле из файла main.cpp, приведенное выше решение заставляет меня объявлять и инициализировать мой async_client в том же файле (в той же функции, даже). Я бы хотел, чтобы глобальный экземпляр клиента хранился в другом файле! - person mrlenbenquet; 10.11.2016