我嘗試使用 paho 庫實作一個異步 MQTT 客戶端,它接收關于主題“請求”的訊息,制定一個字串并將回應放在主題“回應”上。我使用回呼來處理傳入的訊息。
#include "mqtt/async_client.h"
#include "mqtt/topic.h"
const std::string SERVER_ADDRESS {"tcp://localhost:2883"};
const std::string CLIENT_ID {"test_client"};
class TestCallback : public virtual mqtt::callback
{
// the mqtt client
mqtt::async_client& cli_;
// (re)connection success
void connected(const std::string& cause) override
{
cli_.subscribe("request", 0);
}
// callback for when a message arrives.
void message_arrived(mqtt::const_message_ptr msg) override
{
if( msg->get_topic() == "request" )
{
/* format response message here and put it into (string) msg */
mqtt::message_ptr pubmsg = mqtt::make_message("response", msg);
pubmsg->set_qos(2);
//// PROBLEMATIC CODE ////
cli_.publish(pubmsg)->wait();
//////////////////////////
}
}
public:
TestCallback(mqtt::async_client& cli)
: cli_(cli) {}
};
int main(int argc, char** argv)
{
mqtt::async_client cli(SERVER_ADDRESS, CLIENT_ID);
TestCallback cb(cli);
cli.set_callback(cb);
mqtt::connect_options connOpts = mqtt::connect_options_builder()
.clean_session(false)
.automatic_reconnect()
.finalize();
try
{
cli.connect(connOpts)->wait();
}
catch (const mqtt::exception& exc)
{
std::cerr << "[ERROR] " << exc.what() << std::endl;
return 1;
}
// run until the application is shut down
while (std::tolower(std::cin.get()) != 'q')
;
try
{
cli.disconnect()->wait();
}
catch (const mqtt::exception& exc)
{
std::cerr << "[ERROR] " << exc.what() << std::endl;
return 1;
}
return 0;
}
當我嘗試發布回應訊息時出現問題,因為客戶端似乎無限期地等待。對此負責的是wait在令牌上使用的函式來跟蹤已發布訊息的狀態(參考)。據我了解,這必須完成,尤其是在使用更高級別的 QoS 時,以確保一切順利。
洗掉對 的呼叫后wait(),它按預期作業。但我不確定這是否能確保正確發布訊息。
這樣做的正確方法是什么?
uj5u.com熱心網友回復:
我將在這里進行猜測,因為我真的不知道異步在 C 中是如何作業的。
MQTT 客戶端有一個訊息處理執行緒,它處理所有傳入和傳出的 TCP 資料包,因為它們在套接字上到達/離開。當新的 MQTT 訊息到達時,它會呼叫訊息處理程式回呼 ( message_arrived),您可以在其中呼叫publish并wait完成它。但是因為呼叫wait有效地阻塞message_arrived了訊息處理執行緒不能繼續。這意味著它無法處理publish完成所需的 3 條腿 QOS2 握手,因此它掛起。
我還會猜測,如果您將發布更改為 QOS 0,它將完成,但也會因 QOS 1 失敗,因為這需要訊息處理執行緒發送/接收多條訊息才能繼續。
不等待發布完成可能是正確的解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/460444.html
上一篇:成員函式的模板推導
