MQTT(32202): 正在发布过多的消息

文章讲述了作者在测试MQTT消息发布时遇到异常,发现是由于Qos不为0导致的消息堆积。解决方案包括将Qos设置为0,调整MaxInflight客户端连接参数,并考虑添加消息发送数量控制。
摘要由CSDN通过智能技术生成

最近在测试MQTT消息发布时,遇到异常信息

正在进行过多的发布 (32202)
    at org.eclipse.paho.client.mqttv3.internal.ClientState.send(ClientState.java:527)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms.internalSend(ClientComms.java:163)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms.sendNoWait(ClientComms.java:193)
    at org.eclipse.paho.client.mqttv3.MqttTopic.publish(MqttTopic.java:128)
    at test.MqttSyncTest.main(MqttSyncTest.java:70)

查询资料后了解到,当发布消息Qos不为0时,MqttTopic的publish方法会记录消息并在内部线程池中确认消息已送达。

跟踪publish方法:publish-》comms.sendNoWait-》ClientComms.class:this.internalSend-》ClientState.class:clientState.send->异常位置:if (actualInFlight >= this.maxInflight);继续向下查看代码,可以看到 actualInFlight 消息Qos不为0时处理规则:

       switch(innerMessage.getQos()) {

继续查找actualInFlight的变化过程,发现clientState.get()和clientState.decrementInFlight()两个方法:

在publish跟踪过程comms.sendNoWait位置,ClientComms类中发现:CommsSender和ExecutorService

其中CommsSender的run方法,出现message = clientState.get();

该位置调用内容中有:actualInFlight++;语句,对actualInFlight变量进行自增过程。

在ClientState.class的notifyComplete中,调用decrementInFlight方法,对actualInFlight变量进行自减过程。

解决:

1、消息发布时,Qos设置为0。

2、调整客户端连接参数:MaxInflight

MqttConnectOptions        conOptions;

this.clientState.setMaxInflight(conOptions.getMaxInflight());

3、改变发送规则,添加消息发送数量控制。

以下是使用C++ paho mqtt库中的mqtt::topic发布json对象的示例代码: ```c++ #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <json/json.h> #include "mqtt/async_client.h" using namespace std; const string ADDRESS("tcp://localhost:1883"); const string CLIENTID("AsyncPublisher"); const string TOPIC("test"); const int QOS = 1;const int TIMEOUT = 10000L; class callback : public virtual mqtt::callback { public: virtual void connection_lost(const std::string& cause) { cout << "\nConnection lost" << endl; if (!cause.empty()) cout << "\tcause: " << cause << endl; } virtual void delivery_complete(mqtt::delivery_token_ptr token) { cout << "\n\tDelivery complete for token: " << (token ? token->get_message_id() : -1) << endl; } }; int main(int argc, char* argv[]) { mqtt::async_client client(ADDRESS, CLIENTID); mqtt::connect_options connOpts; connOpts.set_keep_alive_interval(20); connOpts.set_clean_session(true); callback cb; client.set_callback(cb); try { mqtt::token_ptr conntok = client.connect(connOpts); conntok->wait_for_completion(); Json::Value root; root["name"] = "John"; root["age"] = 25; root["email"] = "john@example.com"; string json_str = root.toStyledString(); mqtt::message_ptr pubmsg = mqtt::make_message(TOPIC, json_str); pubmsg->set_qos(QOS); mqtt::delivery_token_ptr pubtok = client.publish(pubmsg); pubtok->wait_for_completion(TIMEOUT); cout << "Message '" << json_str << "' published to topic '" << TOPIC << "'" << endl; client.disconnect()->wait_for_completion(); } catch (const mqtt::exception& exc) { cerr << exc.what() << endl; return 1; } return 0; } ``` 在这个示例中,我们使用了Jsoncpp库来创建一个Json对象,并将其转换为字符串。然后,我们使用mqtt::make_message()函数创建一个mqtt::message_ptr对象,该对象包含要发布的主题和消息。最后,我们使用mqtt::async_client类的publish()函数将消息发布到主题上。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值