C++的MQTT开发:使用Paho的C++接口实现消息发布、订阅、连接RabbitMQ

C++ Paho实现MQTT消息发布功能

要使用paho的cpp接口实现发布MQTT消息的功能,需要进行以下步骤:

  1. 安装paho库:首先从paho官方网站下载并安装paho的C++库。可以从https://www.eclipse.org/paho/clients/cpp/ 下载适合操作系统的版本。

  2. 创建MQTT客户端:可以使用mqtt::client类来创建一个客户端,如下所示:

mqtt::client client("tcp://broker.example.com:1883", "clientId");

在上面的代码中,broker.example.com是您的MQTT代理服务器的地址,1883是MQTT代理服务器的默认端口。clientId是客户端的唯一标识符,可以自己选择一个适合的名字。

  1. 设置连接选项:创建客户端后可以设置一些连接选项,例如设置用户名和密码,设置遗嘱消息等。以下是示例代码:
mqtt::connect_options connOpts;
connOpts.set_user_name("username");
connOpts.set_password("password");
connOpts.set_will(mqtt::message("topic", "offline", 1, true));

在上面的代码中,usernamepassword是您的MQTT代理服务器的登录凭据。topic是遗嘱消息的主题,offline是遗嘱消息的内容,1是遗嘱消息的QoS级别(Quality of Service),true表示遗嘱消息是保留的。

  1. 连接到MQTT代理服务器:使用mqtt::client对象的connect方法连接到MQTT代理服务器,如下所示:
client.connect(connOpts);
  1. 发布消息:使用mqtt::client对象的publish方法发布消息。以下是一个示例代码:
std::string payload = "Hello, MQTT!";
client.publish("topic", payload.c_str(), payload.length());

在上面的代码中,topic是消息的主题,payload是消息的内容。您可以根据需要修改这些值。

  1. 断开连接:在完成消息发布后,您可以使用mqtt::client对象的disconnect方法断开与MQTT代理服务器的连接,如下所示:
client.disconnect();

这是使用paho的cpp接口发布MQTT消息的基本步骤,实际应用中可能需要处理更多的错误和异常情况。参考paho的官方文档和示例代码来进一步了解和掌握paho的cpp接口的使用。

完整的C++ Paho消息发布的代码演示

#include <iostream>
#include <cstring>
#include "mqtt/async_client.h"const std::string SERVER_ADDRESS("tcp://broker.example.com:1883");
const std::string CLIENT_ID("clientId");
const std::string TOPIC("topic");class mqtt_callback : public virtual mqtt::callback
{void connection_lost(const std::string& cause) override{std::cout << "\nConnection lost! Cause: " << cause << std::endl;}void delivery_complete(mqtt::delivery_token_ptr token) override{std::cout << "Message delivery complete!" << std::endl;}
};int main(int argc, char* argv[])
{try{mqtt::async_client client(SERVER_ADDRESS, CLIENT_ID);mqtt::connect_options conn_opts;mqtt_callback cb;client.set_callback(cb);client.connect(conn_opts);std::string payload = "Hello, MQTT!";mqtt::message_ptr pubmsg = mqtt::make_message(TOPIC, payload);client.publish(pubmsg);client.disconnect();}catch (const mqtt::exception& exc){std::cerr << "Error: " << exc.what() << std::endl;return 1;}return 0;
}

在这段代码中,我们包含了必要的头文件,并定义了MQTT服务器地址、客户端ID和主题。我们还定义了一个自定义的回调类mqtt_callback,它继承自mqtt::callback,用于处理连接丢失和消息传递完成事件。

main()函数内部创建了一个带有服务器地址和客户端ID的mqtt::async_client对象。我们还创建了一个mqtt::connect_options对象来指定连接选项。使用client.set_callback(cb)为客户端设置回调函数,其中cbmqtt_callback类的一个实例。

我们使用client.connect(conn_opts)建立与MQTT服务器的连接。如果连接成功,我们使用mqtt::make_message()创建一个带有所需负载和主题的MQTT消息。

最后,使用client.publish(pubmsg)发布消息,并使用client.disconnect()断开与MQTT服务器的连接。

客户端:C++ Paho实现 MQTT的客户端

同步客户端:mqtt::client

在paho库中,mqtt::clientmqtt::async_client是MQTT客户端的两种不同实现方式。

mqtt::client是同步的客户端实现,它在发送和接收消息时会阻塞当前线程,直到操作完成或发生超时。这意味着您需要手动管理线程和处理并发操作。使用mqtt::client可以更容易地编写简单的同步代码,特别适用于简单的MQTT应用程序或在没有并发需求的情况下。

以下是使用mqtt::client的示例代码:

mqtt::client client("tcp://broker.example.com:1883", "clientId");// Connect to the MQTT broker
client.connect();// Publish a message
client.publish("topic", "Hello, MQTT!");// Subscribe to a topic
client.subscribe("topic");// Wait for incoming messages
mqtt::message_ptr msg = client.consume_message();// Disconnect from the MQTT broker
client.disconnect();

异步客户端:mqtt::async_client

另一方面,mqtt::async_client是异步的客户端实现,它使用了异步操作和回调函数来处理发送和接收消息,不会阻塞当前线程。这意味着您可以在一个线程中同时处理多个操作,包括异步地发送和接收消息。使用mqtt::async_client可以更好地处理并发操作和复杂的MQTT应用程序。

以下是使用mqtt::async_client的示例代码:

mqtt::async_client client("tcp://broker.example.com:1883", "clientId");// Connect to the MQTT broker
mqtt::token_ptr conntok = client.connect();
conntok->wait();// Publish a message
mqtt::token_ptr pubtok = client.publish("topic", "Hello, MQTT!");
pubtok->wait();// Subscribe to a topic
mqtt::token_ptr subtok = client.subscribe("topic");
subtok->wait();// Wait for incoming messages
client.start_consuming();// Disconnect from the MQTT broker
mqtt::token_ptr disctok = client.disconnect();
disctok->wait();

虽然mqtt::async_client提供了更强大的功能和更好的并发性能,但它需要更多的代码和处理异步回调函数。如果应用程序需要处理大量的并发操作或实现复杂的MQTT逻辑,推荐使用mqtt::async_client。但如果只需要简单的同步操作或在单线程环境中运行较简单的MQTT应用程序,那么使用mqtt::client可能更合适。应该根据您的具体需求和应用程序的复杂性选择适合的客户端实现方式。

使用C++ Paho连接rabbitmq

下面是一个简单的示例代码,演示了如何使用Paho C++库连接到RabbitMQ并发布和订阅消息:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <mqtt/async_client.h>const std::string SERVER_ADDRESS("tcp://localhost:1883");
const std::string CLIENT_ID("paho_cpp_async");
const std::string TOPIC("test_topic");class callback : public virtual mqtt::callback, public virtual mqtt::iaction_listener
{
private:mqtt::async_client& client_;public:callback(mqtt::async_client& client) : client_(client) {}void connection_lost(const std::string& cause) override {std::cout << "\nConnection lost" << std::endl;if (!cause.empty())std::cout << "\tcause: " << cause << std::endl;}void delivery_complete(mqtt::delivery_token_ptr token) override {}void message_arrived(const mqtt::const_message_ptr msg) override {std::cout << "Message arrived: " << msg->get_payload_str() << std::endl;}void on_failure(const mqtt::token& tok) override {std::cout << "Connection attempt failed" << std::endl;}void on_success(const mqtt::token& tok) override {std::cout << "Connection attempt successful" << std::endl;// 发布消息mqtt::message_ptr pubmsg = mqtt::make_message(TOPIC, "Hello from Paho C++");pubmsg->set_qos(1);client_.publish(pubmsg);}
};int main(int argc, char* argv[])
{mqtt::async_client client(SERVER_ADDRESS, CLIENT_ID);callback cb(client);client.set_callback(cb);mqtt::connect_options connOpts;connOpts.set_clean_session(true);try {std::cout << "Connecting to the MQTT server..." << std::endl;mqtt::token_ptr conntok = client.connect(connOpts);conntok->wait();std::cout << "Connected!" << std::endl;// 订阅消息client.subscribe(TOPIC, 1);while (true) {// 持续监听消息usleep(1000000);}} catch (const mqtt::exception& exc) {std::cerr << "Error: " << exc.what() << std::endl;return 1;}return 0;
}

这个示例代码创建了一个异步的MQTT客户端,并连接到RabbitMQ服务器。它使用一个回调类来处理与连接、消息到达等事件相关的回调。在on_success回调中,它发布一条消息。在message_arrived回调中,它处理接收到的消息。

  1. 编译和运行代码:使用适当的编译器和选项,将代码编译为可执行文件。确保已经安装了Paho C++库,并在编译时链接到该库。然后运行可执行文件。

这样就可以使用Paho C++库连接到RabbitMQ并进行消息发布和订阅操作了。

本示例代码仅提供了一个基本的框架,需要根据自己的需求进行更多的自定义和错误处理。此外,确保已正确配置RabbitMQ服务器的连接参数,如服务器地址、端口和认证信息等。

补充说明

连续发送消息的注意事项

在连续发送多条消息时避免频繁断开和重连MQTT客户端。频繁的断开和重连会增加网络开销和延迟,并且可能会对MQTT服务器造成不必要的负担。保持MQTT客户端的持久连接,并在需要时使用同一连接发送多条消息。

以下示例展示如何保持MQTT客户端的持久连接,并连续发送多条消息:

mqtt::async_client client("tcp://broker.example.com:1883", "clientId");// Connect to the MQTT broker
mqtt::connect_options connOpts;
connOpts.set_keep_alive_interval(60);  // 设置心跳间隔为60秒
connOpts.set_clean_session(false);     // 设置为非清理会话模式
mqtt::token_ptr conntok = client.connect(connOpts);
conntok->wait();// Publish multiple messages
for (int i = 0; i < 10; ++i) {std::string topic = "topic";std::string payload = "Message " + std::to_string(i);mqtt::message_ptr pubmsg = mqtt::make_message(topic, payload);mqtt::token_ptr pubtok = client.publish(pubmsg);pubtok->wait();
}// Disconnect from the MQTT broker
mqtt::token_ptr disctok = client.disconnect();
disctok->wait();

在上述示例中,使用set_keep_alive_interval()方法设置了心跳间隔为60秒,这样可以确保MQTT客户端与服务器保持持久连接。我们还使用set_clean_session(false)将客户端设置为非清理会话模式,这样即使客户端断开连接,会话状态也会保留。

然后,我们使用一个循环来连续发布多条消息。每次循环中,我们创建一个新的消息并使用client.publish()发送。通过保持持久连接,我们可以在同一连接上连续发送多条消息,而不需要频繁断开和重连。

最后,使用client.disconnect()来断开与MQTT服务器的连接。

具体的MQTT应用程序可能会有不同的需求和限制。如果应用程序需要在发送消息之间有较长的时间间隔,或者需要处理长时间的非活动状态,那么可以考虑在一段时间后断开连接,并在需要时重新连接。为了连续发送多条消息,建议保持MQTT客户端的持久连接,避免频繁断开和重连。这样可以减少网络开销并提高性能。

如果无需同步,是否需要wait

如果不需要等待异步操作完成,那么在使用mqtt::token对象的时候可以选择不调用wait方法。wait方法会阻塞当前线程,直到操作完成或发生超时。如果您不调用wait方法,程序将继续执行下一行代码,而不会等待操作完成。

以下是一个不调用wait方法的情况:

mqtt::async_client client("tcp://broker.example.com:1883", "clientId");// Connect to the MQTT broker
mqtt::token_ptr conntok = client.connect();
// 不调用wait方法,程序继续执行下一行代码// Publish a message
mqtt::token_ptr pubtok = client.publish("topic", "Hello, MQTT!");
// 不调用wait方法,程序继续执行下一行代码// Subscribe to a topic
mqtt::token_ptr subtok = client.subscribe("topic");
// 不调用wait方法,程序继续执行下一行代码// Wait for incoming messages
client.start_consuming();// Disconnect from the MQTT broker
mqtt::token_ptr disctok = client.disconnect();
// 不调用wait方法,程序继续执行下一行代码

上述示例创建了一个mqtt::async_client对象,并进行了连接、发布消息、订阅主题和断开连接的操作。但是我们没有调用wait方法等待操作完成。这意味着程序将继续执行下一行代码,而不会等待操作完成。

请注意,如果不调用wait方法,将无法确定操作是否成功完成。如果需要获取操作的结果或处理操作的回调函数,可能需要调用wait_for_completion方法或使用其他适当的方式来处理异步操作的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/24573.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FM151A,FM171B和利时工控

FM151A,FM171B和利时工控&#xff0c;DCS系统应该具备以下特点&#xff1a;1.系统具备开放的体系结构&#xff0c;可以提供多层的开放数据接口&#xff1b;FM151A,FM171B和利时工控。2.系统应具备强大的处理功能&#xff0c;中型分布式控制系统大型数据采集监控系统功能。FM151…

[数据集][目标检测]室内积水检测数据集VOC+YOLO格式761张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;761 标注数量(xml文件个数)&#xff1a;761 标注数量(txt文件个数)&#xff1a;761 标注类别…

Spark Python环境搭建与优化:深入剖析四个方面、五个方面、六个方面及七个关键要点

Spark Python环境搭建与优化&#xff1a;深入剖析四个方面、五个方面、六个方面及七个关键要点 在大数据处理领域&#xff0c;Apache Spark凭借其出色的性能和灵活性备受瞩目。而要在Python中利用Spark的强大功能&#xff0c;首先需要搭建一个稳定且高效的Spark Python环境。本…

使用小黄鸟(HttpCanary)、VMOS Pro虚拟机对手机APP进行抓包(附带软件)

老规矩先看&#xff0c;效果图&#xff1a; 文章很详细&#xff0c;希望可以耐心看完&#xff0c;保证可以学会抓包&#xff0c;不再走冤枉路&#xff0c;小编在之前看过太多类似文章&#xff0c;折腾了太久才搞懂的&#xff0c;写这篇文章就是不想希望你们像小编一样再花时间…

C++ 20新特性之三向比较运算符

概述 在C中&#xff0c;如果需要对两个自定义类的对象进行比较&#xff0c;我们通常要单独定义6个比较运算符&#xff1a;、!、<、<、>、>。这不仅繁琐&#xff0c;还很容易出错&#xff0c;特别是当比较逻辑复杂时&#xff0c;稍有不慎就会引发不一致的比较结果。…

最新的ffmepg.js前端VUE3实现视频、音频裁剪上传功能

package.json "dependencies": {"ffmpeg/ffmpeg": "^0.12.10","ffmpeg/util": "^0.12.1" }vue3组件代码 根据需要更改 <script setup lang"ts"> import { FFmpeg } from ffmpeg/ffmpeg; import { fetchF…

mac无法读取windows分区怎么办 苹果硬盘怎么读取

对于Mac电脑用户但有Windows系统使用需求的&#xff0c;我们可以通过Boot Camp启动转换助理安装Windows分区这个方案来解决&#xff0c;不过因为两个系统的磁盘格式不同&#xff0c;相应的也会产生一些问题&#xff0c;例如无法正常读取windows分区。下面本文就详细说明mac无法…

在Java中使用SeleniumAPI,超详细

Java中 Selenium相关操作 1 定位元素 1.1 css选择器定位元素 就是定位到页面的元素&#xff0c;本质上就是一个一个的语法 下面举几个具体的例子&#xff1a; 类选择器 按照给定的 class 属性的值&#xff0c;选择所有匹配的元素。 语法&#xff1a;.classname 例子&am…

Sass详细介绍

Sass&#xff08;Syntactically Awesome Stylesheets&#xff09;是一种CSS预处理器&#xff0c;用于增强CSS的功能和灵活性。以下是对Sass的详细介绍&#xff0c;采用分点表示和归纳的方式&#xff1a; 1. Sass的概述 Sass是一种CSS预处理器&#xff0c;它扩展了CSS的语法和…

力扣1358.包含所有三种字符的子字符串数目

力扣1358.包含所有三种字符的子字符串数目 遍历左端点 找到最小的子字符串 res n - j(右边全部) class Solution {public:int numberOfSubstrings(string s) {unordered_map<char,int> cnt;int n s.size(),res0,count3;for(int i0,j0;j<n;j){if(!cnt.count(s[j])…

Python如何巧妙回应:深入解析Python的回应策略与技巧

Python如何巧妙回应&#xff1a;深入解析Python的回应策略与技巧 在编程的世界里&#xff0c;Python以其简洁、易读和强大的功能库赢得了众多开发者的青睐。然而&#xff0c;当我们与Python程序进行交互时&#xff0c;如何巧妙地回应其输出或错误信息&#xff0c;成为了提高编…

数字签名及其作用

一、技术难点 数字签名作为信息安全领域的关键技术之一&#xff0c;其技术难点主要体现在以下几个方面&#xff1a; 算法选择&#xff1a;不同的数字签名算法具有不同的安全性、效率和应用场景。如RSA、ECDSA、DSA等算法各有优劣&#xff0c;如何根据实际需求选择合适的算法是…

flutter 解析json另类封装方式 List<bean>,哈哈哈

flutter 解析json另类封装方式&#xff0c;哈哈哈 日常学习&#xff0c;仅供参考&#xff0c;不喜 勿喷 http请求数据泛型解析封装&#xff0c;需要判断泛型数据类型再根据类型解析&#xff0c;本文只抽取了list演示 核心代码 import dart:convert;import package:webwsyn/h…

素颜个人引导页源码

源码介绍 素颜个人引导页源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 效果预览 源码下载 素颜个人引导页源码

2005-2022年各省居民人均消费支出数据(无缺失)

2005-2022年各省居民人均消费支出数据&#xff08;无缺失&#xff09; 1、时间&#xff1a;2005-2022年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;全体居民人均消费支出 4、范围&#xff1a;31省 5、缺失情况&#xff1a;无缺失 6、指标解释 居民人…

matlab(实例):滤波器(低通、带通、高通,使用butter函数、filter函数)

一、题目&#xff1a;已知一个时域信号&#xff0c;包含三个频率&#xff08;50Hz、150Hz、300Hz&#xff09;&#xff0c;分别设计并使用低通滤波器、带通滤波器、高通滤波器&#xff0c;对其进行滤波&#xff0c;画出滤波信号的时域图和频谱图。 二、解题过程&#xff1a; ①…

区块链的基本原理和优势

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

无人机电机选型

2306的意思是电机定子直径23MM&#xff0c;定子高度6MM.在相同KV值的情况下电机的定子体积越大&#xff0c;扭矩越大&#xff1a;KV的意思是每增加1V的电压电机转速增加多少。同参数的电机KV越低&#xff0c;在低速的情况下能带动更大的质量。这也就解释了竞速机选用更高KV值的…

【Java】解决Java报错:NoClassDefFoundError

文章目录 引言1. 错误详解2. 常见的出错场景2.1 类路径配置错误2.2 依赖库缺失2.3 类文件被删除或损坏2.4 类加载器问题 3. 解决方案3.1 检查类路径配置3.2 检查依赖库3.3 检查类文件3.4 调试类加载器问题 4. 预防措施4.1 使用构建工具管理依赖4.2 定期进行构建和测试4.3 使用I…

了解光伏储能技术的应用场景和优势

光伏发电是指利用太阳能电池板将太阳光转化为电能的过程。其优点在于清洁、高效、可再生&#xff0c;但光伏发电需要同时也存在间歇性和不稳定性问题。为了解决这一问题&#xff0c;光伏储能技术得到了广泛应用。其基本原理是将白天无法消耗的电能储存起来&#xff0c;以供需要…