C++调用paho-mqtt-cpp异步发布需使用mqtt::async_client,连接成功后调用publish()立即返回,须预先设置connection_lost_callback和delivery_complete_callback,发布时传mqtt::message对象且主题为std::string。
直接使用 mqtt::async_client 类,它默认走异步路径;同步发布(publish())会阻塞,而异步必须配合 delivery_complete_callback 和 connection_lost_callback 才能真正“不卡主线程”。
关键点:异步发布调用 publish() 后立即返回,消息实际发送由底层线程池处理;但你必须在连接成功后才调用,否则抛 std::runtime_error(错误信息含 "not connected")。
cli.set_connected_callback()、cli.set_connection_lost_callback()
mqtt::message 对象,不能只传字符串;主题名需为 std::string,不能是 C 风格字符串字面量(如 "topic" 可以,但 "topic\0" 会截断)delivery_complete_callback 并注册,否则无法知道 QoS > 0 消息是否被 broker 确认mqtt::async_client cli("tcp://localhost:1883", "cpp_client");
cli.set_connection_lost_callback([](const std::string& cause) {
std::cout << "Connection lost: " << cause << std::endl;
});
cli.connect()->wait(); // wait() 是阻塞的,但 connect() 返回 future,可改为 async + then
auto tok = cli.publish("sensor/temp", "23.5", 1, false);
tok->wait(); // 这里 wait() 是等发布动
作提交完成,不是等 broker 确认paho-mqtt-cpp 的异步订阅本身不自动触发回调——它只把消息推到内部队列,你必须显式调用 cli.start_consuming() 启动消费线程,或手动轮询 cli.consume_message()。没这一步,message_arrived_callback 根本不会被调用。
常见错误是:调用了 subscribe(),也注册了 set_message_arrived_callback(),但忘了启动消费机制,结果消息静默丢失。
start_consuming() 启动后台线程,适合长期运行程序;但它不能中途停,只能靠 stop_consuming()(注意:不是所有版本都支持 stop)consume_message(std::chrono::milliseconds) 在主循环中非阻塞拉取,超时返回空指针void(const mqtt::message&),捕获异常会导致整个消费线程崩溃(建议加 try/catch)cli.set_message_arrived_callback([](const mqtt::message& msg) {
try {
std::cout << "Received: " << msg.get_payload_str() << " on " << msg.get_topic() << std::endl;
} catch (...) { /* 防止异常逃逸 */ }
});
cli.subscribe("sensor/#", 1)->wait();
cli.start_consuming(); // 必须有!异步发布下,publish() 成功只表示消息已入发送队列,不代表 broker 已接收。QoS 1 或 2 的消息只有收到 PUBACK/PUBREC 才算真正送达,这个状态通过 delivery_complete_callback 通知。
如果你没设这个回调,或者回调里没做日志/计数,就完全不知道消息是否落地——尤其在网络抖动时,broker 可能丢弃未确认消息,而客户端毫无感知。
const mqtt::idelivery_token&,调用 token.get_message_id() 可关联原始消息token.is_complete()
offline_buffer(默认大小 1000),超出后新消息直接丢弃,且不报错cli.set_delivery_complete_callback([](mqtt::idelivery_token_ptr tok) {
if (tok && tok->is_complete()) {
std::cout << "Message delivered, ID=" << tok->get_message_id() << std::endl;
}
});set_automatic_reconnect() 只控制 TCP 层重连行为,它不会自动恢复订阅(subscribe)、也不会重新绑定 callback。断连重连后,你得手动补订主题,否则消息收不到。
更隐蔽的问题是:重连成功触发 connected_callback,但此时 client 内部状态可能还没完全就绪(比如 session 还没重建),立刻 subscribe() 可能失败并抛异常。
connected_callback 里再次调用 subscribe(),且对返回的 itoken 调用 wait() 或监听其完成mosquitto_sub -t 'test' -d 手动模拟 broker 断连,比单纯 kill 进程更能暴露状态不同步问题自动重连不是银弹——它解决不了会话丢失、消息重复、订阅漂移这些 MQTT 协议层问题。
# c++
# String
# Session
# try
# catch
# Token
# const
# 字符串
# void
# 循环
# 风格字符串
# 指针
# 线程
# 主线程
# 空指针
# 对象
# 事件
# 异步
# 回调
# 还没
# 报错
# 中非
# 收不到
# 若需
# 不代表
# 问题是
# 你没
# 更能
相关文章:
香港服务器网站推广:SEO优化与外贸独立站搭建策略
佛山网站制作系统,佛山企业变更地址网上办理步骤?
网站网页制作专业公司,怎样制作自己的网页?
如何在宝塔面板中创建新站点?
广东企业建站网站优化与SEO营销核心策略指南
昆明网站制作哪家好,昆明公租房申请网上登录入口?
成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?
如何制作网站标识牌,动态网站如何制作(教程)?
如何在阿里云ECS服务器部署织梦CMS网站?
独立制作一个网站多少钱,建立网站需要花多少钱?
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
python的本地网站制作,如何创建本地站点?
如何确保西部建站助手FTP传输的安全性?
如何通过多用户协作模板快速搭建高效企业网站?
Android滚轮选择时间控件使用详解
如何在景安服务器上快速搭建个人网站?
怎么将XML数据可视化 D3.js加载XML
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
深圳企业网站制作设计,在深圳如何网上全流程注册公司?
长沙企业网站制作哪家好,长沙水业集团官方网站?
如何用景安虚拟主机手机版绑定域名建站?
如何在阿里云服务器自主搭建网站?
武清网站制作公司,天津武清个人营业执照注销查询系统网站?
东莞专业制作网站的公司,东莞大学生网的网址是什么?
制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?
利用JavaScript实现拖拽改变元素大小
Python文件管理规范_工程实践说明【指导】
如何快速搭建高效香港服务器网站?
建站之星2.7模板快速切换与批量管理功能操作指南
潍坊网站制作公司有哪些,潍坊哪家招聘网站好?
建站之星多图banner生成与模板自定义指南
深入理解Android中的xmlns:tools属性
制作门户网站的参考文献在哪,小说网站怎么建立?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
如何选择香港主机高效搭建外贸独立站?
建站为何优先选择香港服务器?
宝塔建站教程:一键部署配置流程与SEO优化实战指南
c# 在高并发下使用反射发射(Reflection.Emit)的性能
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
湖北网站制作公司有哪些,湖北清能集团官网?
黑客如何通过漏洞一步步攻陷网站服务器?
广州建站公司哪家好?十大优质服务商推荐
宝塔Windows建站如何避免显示默认IIS页面?
常州企业建站如何选择最佳模板?
定制建站流程步骤详解:一站式方案设计与开发指南
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?
成都网站制作公司哪家好,四川省职工服务网是做什么用?
建站之星如何通过成品分离优化网站效率?
如何选择高效稳定的ISP建站解决方案?
*请认真填写需求信息,我们会在24小时内与您取得联系。