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

一 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.mzph.cn/news/112806.shtml

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

相关文章

推荐一种更高效的打字输入法——双拼输入法

简介 双拼&#xff08;也称双打&#xff09;是一种建立在拼音输入法基础之上的文字输入方法&#xff0c;可视为全拼的一种改进。它通过将每个汉字拼音的声母和韵母各自映射到某个按键上&#xff0c;使得每个汉字最多用两个按键表示&#xff0c;从而极大地提高了拼音输入法的输…

leetcode:105从前序与中序遍历序列构造二叉树

105&#xff1a;从前序与中序遍历序列构造二叉树 啊&#xff0c;好久都没有更新算法题目了。曾今是C&#xff0c;如今是Java&#xff0c;感慨啊。 像树这样的算法题&#xff0c;基本都逃不开递归。递归的思想是&#xff1a;将大任务拆分为小任务。我们不妨构建一个函数&#…

LLM ReAct: 将推理和行为相结合的通用范式 学习记录

LLM ReAct 什么是ReAct? LLM ReAct 是一种将推理和行为相结合的通用范式,可以让大型语言模型(LLM)根据逻辑推理(Reason),构建完整系列行动(Act),从而达成期望目标。LLM ReAct 可以应用于多种语言和决策任务,例如问答、事实验证、交互式决策等,提高了 LLM 的效率、…

2022年亚太杯APMCM数学建模大赛B题高速列车的优化设计求解全过程文档及程序

2022年亚太杯APMCM数学建模大赛 B题 高速列车的优化设计 原题再现&#xff1a; 2022年4月12日&#xff0c;中国高铁复兴号CR450动车组在开放线上成功实现单车时速435公里&#xff0c;相对速度870公里&#xff0c;创造了高铁动车组列车穿越开放线和隧道速度的世界纪录。新一代…

深度神经网络时与协方差矩阵

平时训练深度神经网络时&#xff0c;什么时候用到了协方差矩阵 在深度神经网络的平时训练过程中&#xff0c;一般情况下不直接使用协方差矩阵。然而&#xff0c;协方差矩阵的概念和相关性的考虑在某些情况下可以对网络的训练和优化起到一定的指导作用。 下面是一些与协方差矩…

用python写一个贪吃蛇的程序能运行能用键盘控制

用python写一个贪吃蛇的程序能运行能用键盘控制 1.源码2.运行效果 1.源码 开发库使用&#xff1a;pygame random 直接在终端运行&#xff1a;pip install pygame pycharm安装库&#xff1a;文件-设置-项目-Python 解释器 import pygame import random# 初始化pygame pygame…

Date3

语法 Date3(year, month, day) 描述 The Date3 function accepts a date expressed as three integers: year, month, and day. It returns a corresponding Date value. If the date is invalid, the Date3 displays an error message. Warning! Make sure that you pass a…

牛客小白月赛79 D

题意&#xff1a; 给定数 x &#xff0c;每次可以选择将 x 变为 x*2 &#xff0c;或是将 x 变为 x1&#xff0c;求 x 变为 2 20 2^{20} 220倍数的最小代价。 思路&#xff1a; 因为对于 2 20 2^{20} 220次方倍数的点无意义&#xff0c;所以总共的点数只用 2 20 2^{20} 220即…

2023年中国轮胎模具需求量、竞争格局及行业市场规模分析[图]

轮胎模具是轮胎生产线中的硫化成形装备&#xff0c;是高技术含量、高精度及高附加值的个性化模具产品&#xff0c;尤其是轮胎的花纹、图案、字体以及其他外观特征的成形都依赖于轮胎模具&#xff0c;因此其制造技术难度较高。其主要功能是通过所成型材料&#xff08;主要是橡塑…

最优化:建模、算法与理论(最优性理论2

5.7 约束优化最优性理论应用实例 5.7.1 仿射空间的投影问题 考虑优化问题 min ⁡ x ∈ R n 1 2 ∣ ∣ x − y ∣ ∣ 2 2 , s . t . A x b \min_{x{\in}R^n}\frac{1}{2}||x-y||_2^2,\\ s.t.{\quad}Axb x∈Rnmin​21​∣∣x−y∣∣22​,s.t.Axb 其中 A ∈ R m n , b ∈ R m …

2024免费的苹果电脑杀毒软件cleanmymac X

苹果电脑怎么杀毒&#xff1f;这个问题自从苹果电脑变得越来越普及&#xff0c;苹果电脑的安全性问题也逐渐成为我们关注的焦点。虽然苹果电脑的安全性相对较高&#xff0c;但仍然存在着一些潜在的威胁&#xff0c;比如流氓软件窥探隐私和恶意软件等。那么&#xff0c;苹果电脑…

uniapp下载附件保存到手机(文件、图片)ios兼容

downloadFile(file)&#xff0c;其中file为下载的文件地址uni.downloadFile图片使用uni.saveImageToPhotosAlbum【安卓、ios都合适】文件使用uni.openDocument【安卓图片也可以用这个&#xff0c;ios会失败】 // 下载文件 export function downloadFile(file) {let acceptArr …

【LeetCode:2316. 统计无向图中无法互相到达点对数 | BFS + 乘法原理】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

大模型LLM相关面试题整理-PEFT

Prefix/Prompt-Tuning&#xff1a;在模型的输入或隐层添加 个额外可训练的前缀 tokens&#xff08;这些前缀是连续的伪 tokens&#xff0c;不对应真实的 tokens&#xff09;&#xff0c;只训练这些前缀参数&#xff1b; Adapter-Tuning&#xff1a;将较小的神经网络层或模块插入…

面试题 01.04. 回文排列

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;面试题 01.04. 回文排列 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 对字符串中各字符计数&#xff0c;若个数为奇数的字符个数大于 1&#xff0c;则不是回文排列&#xff0c;否则是。 …

uniapp 小程序优惠劵样式

先看效果图 上代码 <view class"coupon"><view class"tickets" v-for"(item,index) in 10" :key"item"><view class"l-tickets"><view class"name">10元优惠劵</view><view cl…

c++ 常见类内的关键字

1. override override 是一个关键字&#xff0c;用于显式地标记派生类中重写&#xff08;覆盖&#xff09;基类虚函数的意图。 override 并不会影响程序的执行结果&#xff0c;仅仅是作用于编译阶段&#xff0c;用于检查子类是否真的重写父类函数 作用&#xff1a; 帮助发现错…

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

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

Hive用户中文使用手册系列(一)

Apache Hive 在标题为“Information Platforms and the Rise of the Data Scientist”的文章一文中&#xff0c;Jeff Hammerbacher把“信息平台”描述为“企业摄取(ingest)、处理(process)、生成(generate)信息的行为”与“帮助加速从经验数据中学习”的“中心”。 在Facebook…

Linux之I2C应用编程

I2C-Tools的交叉编译 tar xvf i2c-tools-4.2.tar.xz 首先解压下压缩包 cd i2c-tools-4.2 进入 i2c-tools-4.2目录 make USE_STATIC_LIB1 执行 make 将i2cset ,i2cget ,i2cdump,i2cdetect,i2ctransfer放到板子上 命令直接操作IIC设备 命令行直接操作iic向AP3216C传感器获取数据…