嵌入式mqtt总线架构方案mosquitto+paho

news2024/11/19 7:44:31

一 mqtt通信模型

MQTT 协议提供一对多的消息发布,可以降低应用程序的耦合性,用户只需要编写极少量的应用代码就能完成一对多的消息发布与订阅,该协议是基于<客户端-服务器>模型,在协议中主要有三种身份:发布者(Publisher)、服务器(Broker)以及订阅者(Subscriber)。其中,MQTT消息的发布者和订阅者都是客户端,服务器只是作为一个中转的存在,将发布者发布的消息进行转发给所有订阅该主题的订阅者;发布者可以发布在其权限之内的所有主题,并且消息发布者可以同时是订阅者,实现了生产者与消费者的脱耦,发布的消息可以同时被多个订阅者订阅。

客户端->(发布)->服务器->(订阅)->客户端

MQTT客户端功能:1.发布消息给其它相关的客户端。 2.订阅主题请求接收相关的应用消息。 3.取消订阅主题请求移除接收应用消息。 4.从服务端终止连接。
 

MQTT服务器端功能: MQTT 服务器常被称为 Broker(消息代理),以是一个应用程序或一台设备,它一般为云服务器,比如BTA三巨头的一些物联网平台就是常使用MQTT协议,它是位于消息发布者和订阅者之间,以便用于接收消息并发送到订阅者之中,它的功能有: 1.接受来自客户端的网络连接请求。 2.接受客户端发布的应用消息。 3.处理客户端的订阅和取消订阅请求。 4.转发应用消息给符合条件的已订阅客户端(包括发布者自身)。

二 mosquito

2.1 准备工作

openssl的交叉编译

下载链接:/source/old/index.html
cp openssl-1.1.1g.tar.gz /opt/north/
tar -zxvf openssl-1.1.1g.tar.gz
cd openssl-1.1.1g
mkdir build

./config no-asm -shared --prefix=/opt/mosquitto/arm/ssl/ CC=/opt/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc CXX=/opt/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
make
make install

cmake autoconf 和libtool的安装

apt-get install cmake
apt-get install autoconf
apt-get install libtool

2.2 mosquito下载

官网下载地址:Download | Eclipse Mosquitto

2.3 编译

linux端自行编译

  1. # tar axvf mosquitto-1.5.5.tar.gz

  2. # cd mosquitto-1.5.5

  3. # make

交叉编译

  1. # make CC=arm-xxx-gcc CXX=arm-xxx-g++

  2. # sudo make install

2.3 运行

:默认端口为1883 有需要可以补一下配置信息


三 paho.mqtt.c

3.1 paho下载

eclipse/paho.mqtt.c: An Eclipse Paho C client library for MQTT for Windows, Linux and MacOS. API documentation: https://eclipse.github.io/paho.mqtt.c/

3.2 目录

cd Eclipse-Paho-MQTT-C-1.3.12-Linux/

3.3 编译

3.4 环境

3.5 运行

四 测试demo

4.1 同步

send:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "MQTTClient.h"

#include "MQTTAsync.h"

#define ADDRESS     "tcp://127.0.0.1:1883"

#define CLIENTID    "ClientID1"

#define TOPIC       "topic"

#define QOS         0

#define TIMEOUT     10000L

int main(int argc, char* argv[])

{

    MQTTClient client;

    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;

    MQTTClient_message pubmsg = MQTTClient_message_initializer;

    MQTTClient_deliveryToken token;

    int rc;

    // 创建MQTT客户端

    MQTTClient_create(&client, ADDRESS, CLIENTID,

        MQTTCLIENT_PERSISTENCE_NONE, NULL);

    // 设置连接选项

    conn_opts.keepAliveInterval = 20;

    conn_opts.cleansession = 1;

    conn_opts.MQTTVersion = 3;

    // 连接到MQTT代理服务器

    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)

    {

        printf("连接失败,错误码: %d\n", rc);

        exit(-1);

    }

    printf("连接成功\n");

    // 发布消息

    pubmsg.payload = "Hello, MQTT";

    pubmsg.payloadlen = strlen(pubmsg.payload);

    pubmsg.qos = QOS;

    pubmsg.retained = 0;

    MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);

    printf("发布消息到主题 %s: %s\n", TOPIC, (char*)pubmsg.payload);

    int connect = 0;

    // 等待发布完成

    while( connect < 10 ) {

        MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);

        printf("发布消息到主题 %s: %s\n", TOPIC, (char*)pubmsg.payload);

        rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);

        printf("发布完成\n");

        sleep(2);

        connect++;

    }


 

    // 断开MQTT连接

    MQTTClient_disconnect(client, 10000);

    printf("断开连接\n");

    // 销毁MQTT客户端

    MQTTClient_destroy(&client);

    return rc;

}

recv

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "MQTTClient.h"

int messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *message)

{

    printf("接收到来自主题 %s 的消息:\n", topicName);

    printf("消息内容:");

    if (message->payloadlen > 0) {

        printf("%.*s", message->payloadlen, (char*)message->payload);

    }

    printf("\n");

    // 在这里执行你的消息处理逻辑

    MQTTClient_freeMessage(&message);

    MQTTClient_free(topicName);

    return 1;

}

int main()

{

    // 创建 MQTT 客户端对象并连接到 MQTT 代理

    MQTTClient client;

    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;

    MQTTClient_create(&client, "tcp://127.0.0.1:1883", "ClientID", MQTTCLIENT_PERSISTENCE_NONE, NULL);

    MQTTClient_connect(client, &conn_opts);

    // 订阅感兴趣的主题

    char* TOPIC = "topic";

    int topiclen = strlen(TOPIC);

    MQTTClient_subscribe(client, TOPIC, 0);

    // 循环接收消息

    int rc;

    MQTTClient_message *pubmsg = NULL;

    do {

        rc = MQTTClient_receive(client, &TOPIC, &topiclen, &pubmsg, 1000);

        if (rc == MQTTCLIENT_SUCCESS) {

            messageArrived(NULL, TOPIC, topiclen, pubmsg);

        }

        sleep(2);

    } while (rc != MQTTCLIENT_DISCONNECTED);

    // 断开连接并清理资源

    MQTTClient_disconnect(client, 1000);

    MQTTClient_destroy(&client);

    return rc;

}

4.2 异步

send:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "MQTTAsync.h"

#define ADDRESS     "tcp://localhost:1883"

#define CLIENTID    "ExampleServerPub"

#define TOPIC       "topic"

#define PAYLOAD     "Hello, world!"

#define QOS         0

#define TIMEOUT     10000L

volatile MQTTAsync_token deliveredtoken;

void connectionLost(void *context, char *cause)

{

    printf("connect lost");

}

void messageArrived(void *context, char *topicName, int topicLen, MQTTAsync_message *message);

void onPublish(void* context, MQTTAsync_successData* response);

int main()

{

    MQTTAsync client;

    MQTTAsync_message pubmsg = MQTTAsync_message_initializer;

    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;

    MQTTAsync_responseOptions res = MQTTAsync_responseOptions_initializer;

    int rc;

    MQTTAsync_create(&client,ADDRESS,CLIENTID,MQTTASYNC_PERSISTENCE_ERROR,NULL);

    conn_opts.keepAliveInterval = 20;

    conn_opts.cleansession = 1;

    conn_opts.MQTTVersion = 3;

    MQTTAsync_setCallbacks(client,CLIENTID,connectionLost,NULL,NULL);

    MQTTAsync_connect(client,&conn_opts);

   

    pubmsg.payload = "hello,mqtt";

    pubmsg.payloadlen = strlen(pubmsg.payload);

    pubmsg.qos = QOS;

    pubmsg.retained = 0;

    int connect = 0;

    while( connect < 10 ) {

        sleep(2);

        MQTTAsync_sendMessage(client,TOPIC,&pubmsg,&res);

        MQTTAsync_waitForCompletion(client,res.token,TIMEOUT);

        printf("send msg [%d]\n",connect);

       

        connect++;

    }

    MQTTAsync_disconnectOptions ops;

    MQTTAsync_disconnect(client,&ops);

    MQTTAsync_destroy(&client);


 

}

recv:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "MQTTAsync.h"

#define ADDRESS     "tcp://localhost:1883"

#define CLIENTID    "ExampleClientPub"

#define TOPIC       "topic"

#define PAYLOAD     "Hello, world!"

#define QOS         0

#define TIMEOUT     10000L

int onMessageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* pubmsg)

{

    char* payload = (char*)pubmsg->payload;

    int payloadLen = pubmsg->payloadlen;

    // 在这里处理收到的消息

    printf("Received message on topic: %s\n", topicName);

    printf("Message payload: %.*s\n", payloadLen, payload);

    // 完成消息处理后,记得释放消息对象

    MQTTAsync_freeMessage(&pubmsg);

    MQTTAsync_free(topicName);

    return 1;

}

void onConnectionLost(void *context, char *cause)

{

    printf("connect lost");

}

int main()

{

    int rc;

    MQTTAsync client;

    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;

    MQTTAsync_message pubmsg = MQTTAsync_message_initializer;

    MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;

    MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTASYNC_PERSISTENCE_ERROR, NULL);

   

    // 设置回调函数

    MQTTAsync_setCallbacks(client, NULL, onConnectionLost, onMessageArrived, NULL);

    conn_opts.keepAliveInterval = 20;

    conn_opts.cleansession = 1;

    conn_opts.MQTTVersion = 3;

    // 连接到 MQTT 代理

    if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)

    {

        printf("Failed to connect to broker, return code %d\n", rc);

        exit(EXIT_FAILURE);

    }

     // 等待连接完成

    printf("Connecting to broker...\n");

    while (!MQTTAsync_isConnected(client)) {}

    printf("connect successful\n");

    // 订阅主题

    if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS)

    {

        printf("Failed to subscribe, return code %d\n", rc);

        exit(EXIT_FAILURE);

    }

    // 进入主循环等待消息

    printf("Waiting for messages...\n");

    while (1) {

        sleep(1);

    }

    // 完成后,断开连接并释放资源

    MQTTAsync_disconnect(client, NULL);

    MQTTAsync_destroy(&client);

   

    return 0;

}

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

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

相关文章

力扣第37题 解数独 c++ 难~ 回溯

题目 37. 解数独 困难 相关标签 数组 哈希表 回溯 矩阵 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫…

基于Java的文物管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

GRASP 、SOLID 与 GoF 设计模式

一、GRASP GRASP&#xff1a;通用职责分配软件设计模式(General Responsibility Assignment Software Patterns)&#xff0c;其主要思想是基于单一职责设计软件对象。 思考软件对象设计以及大型构件的流行方式是&#xff0c;考虑其职责、角色和协作。这是被称为职责驱动设计&a…

C++:无法查找或打开 PDB 文件?? 如何解决呢?以及产生原因是什么?

C:无法查找或打开 PDB 文件?? 如何解决呢&#xff1f;以及产生原因是什么&#xff1f; 前言解决办法原因 前言 最近博主在写C时&#xff0c;明明代码都正确&#xff0c;但编译失败。查看原因后发现显示&#xff1a;无法查找或打开 PDB 文件。&#xff08;先介绍解决办法&…

【高等数学】微分中值定理

文章目录 1、极值2、费马引理3、罗尔定理4、拉格朗日中值定理4.1用拉格朗日定理证明基本结论 5、柯西中值定理6、微分中值定理的意义7、三大中值定理的意义 1、极值 若 ∃ δ > 0 ∃δ>0 ∃δ>0&#xff0c;使得 ∀ x ∈ U ( x 0 , δ ) ∀x\in U(x_0,δ) ∀x∈U(x0…

DDD与微服务的千丝万缕

一、软件设计发展过程二、什么是DDD&#xff1f;2.1 战略设计2.2 战术设计2.3 名词扫盲1. 领域和子域2. 核心域、通用域和支撑域3. 通用语言4. 限界上下文5. 实体和值对象6. 聚合和聚合根 2.4 事件风暴2.5 领域事件 三、DDD与微服务3.1 DDD与微服务的关系3.2 基于DDD进行微服务…

2023年中国煤气节能器产量及市场规模分析[图]

煤气节能器行业是指生产和销售用于煤气燃烧系统中的节能器的行业。煤气节能器是一种能够有效提高煤气燃烧效率、降低燃烧过程中的热损失的装置&#xff0c;广泛应用于工业生产、民用燃烧等领域。煤气节能器行业的发展与煤气燃烧技术的发展密切相关&#xff0c;随着煤气燃烧技术…

操作系统期末复习题版详解(含解析)

操作系统期末复习 第一章 操作系统引论 一、Os具有哪几大特征?它们之间有何关系? 【参考答案】OS具有并发、共享、虚拟和异步这4个基本特征。它们之间的关系包含以下几个方面。 并发和共享是OS最基本的特征。为了提高计算机资源的利用率&#xff0c;OS必然要采用多道程序设…

Excel 5s内导入20w条简单数据(ExecutorType.BATCH)Mybatis批处理的应用

文章目录 Excel 5s内导入20w条数据1. 生成20w条数据1.1 使用Excel 宏生成20w条数据1.2 生成成功 2. ExecutorType&#xff1a;批量操作执行器类型2.1 ExecutorType.SIMPLE2.2 ExecutorType.BATCH2.3 ExecutorType.REUSE 3. 20w条数据直接插入数据库3.1 使用ExecutorType.SIMPLE…

成功解决ModuleNotFoundError: No module named ‘docx.text.hyperlink‘

成功解决ModuleNotFoundError: No module named docx.text.hyperlink 目录 解决问题 解决思路 解决方法 解决问题 ModuleNotFoundError: No module named ‘docx.text.hyperlink‘ 解决思路 No module named docx.text.hyperlink"。这个错误通常表示你的代码中缺少了…

react 中ref 属性的三种写法

目录 1. 字符串 ref 2.dom节点上使用回调函数ref 3.React.createRef() 1. 字符串 ref 最早的ref用法。&#xff08;由于效率问题&#xff0c;现在官方不推荐使用这种写法。&#xff09; 1.dom节点上使用&#xff0c;通过this.refs.xxxx来引用真实的dom节点 <input ref&q…

云上智能驾驶三维重建最佳实践

智能驾驶技术的不断发展&#xff0c;正在改变着我们的出行方式和交通系统。作为其中的一个关键技术&#xff0c;三维重建在智能驾驶系统中起着重要的作用。除去车端本身的感知、重建算法&#xff0c;自动驾驶技术的落地与发展需要庞大的云端重建能力支撑&#xff0c;火山引擎多…

魔术《4 Kings 折纸》的三重境界(二)——集合语言和数理逻辑

早点关注我&#xff0c;精彩不错过&#xff01; 上回我们回顾了《4 Kings 折纸》这个魔术的内容和用小学的奇偶性原理解析了操作的过程&#xff0c;详情请戳&#xff1a; 魔术《4 Kings 折纸》的三重境界&#xff08;一&#xff09;——奇偶性原理 今天我们进入后第二境界&…

C++入门篇2

文章目录 C入门篇21、函数重载1.1、函数重载概念1.2、 C支持函数重载的原理 -- 名字修饰(name Mangling) 2、引用2.1、引用概念2.2、引用特性2.3、常引用2.4、使用场景2.5、传值、传引用效率比较2.6、引用和指针的区别 3、内联函数3.1、内联函数概念3.2、内联函数特性 4、auto关…

代码随想录第四十五天|1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

1049. 最后一块石头的重量 题目&#xff1a; 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么…

绿肥红瘦专栏数据的爬取

前言 要想爬专栏&#xff0c;先得爬用户。要想爬用户&#xff0c;三个header参数挡住了去路&#xff1a;x-zst-81&#xff0c;x-zse-93&#xff0c;x-zse-96&#xff0c;经过搜索x-zse-96&#xff0c;定位到设置该字段的位置&#xff1a; 这个t2是固定的值&#xff0c;t0来自于…

Leetcode——字符

520. 检测大写字母 class Solution { public:bool detectCapitalUse(string word) {int big 0, small 0, len word.length();for (int i 0; i < len; i) {if (word[i] > 65 && word[i] < 90) {big;}else {small;}}if (big len || small len) {return tr…

Leetcode—2652.倍数求和【简单】

2023每日刷题&#xff08;四&#xff09; Leetcode—2652.倍数求和 实现代码 int sumOfMultiples(int n){int ans 0;int i 1;for(; i < n; i) {if((i % 3 0) || (i % 5 0) || (i % 7 0)) {ans i;}}return ans; }测试结果 之后我会持续更新&#xff0c;如果喜欢我的文…

计算机服务器中了勒索病毒怎么解决,勒索病毒解密流程,数据恢复

计算机服务器中了勒索病毒是一件非常令人头疼的事情&#xff0c;勒索病毒不仅会加密企业服务器中的数据&#xff0c;还会对企业计算机系统带来损害&#xff0c;严重地影响了企业的正常运转。最近&#xff0c;云天数据恢复中心工程师总结了&#xff0c;今年以来网络上流行的勒索…

非关系型数据库-Redis

一、缓存概念 缓存是为了调节速度不一致的两个或多个不同的物质的速度&#xff0c;在中间对速度较慢的一方起到加速作用&#xff0c;比如CPU的一级、二级缓存是保存了CPU最近经常访问的数据&#xff0c;内存是保存CPU经常访问硬盘的数据&#xff0c;而且硬盘也有大小不一的缓存…