05--MQTT物联网协议

一、MQTT的概念

MQTT 协议快速入门 2025:基础知识和实用教程 | EMQ

1.MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎,能够实现传感器、执行器和其它设备之间的高效通信。

2.订阅与发布规则

二、MQTT 代理服务器

三、Mosquitto 代理服务器

Eclipse Mosquitto 也是一款开源的 MQTT Broker,兼容 MQTT 协议的 5.0、3.1.1 和 3.1 版本。Mosquitto 体积小巧,既可以运行在低功耗的单板计算机上,也可以部署在企业级服务器上。它采用 C 语言编写,可以用 C 库实现 MQTT 客户端。它支持 Windows、Mac、Linux 和 Raspberry Pi 等多种平台,为每个平台提供了方便安装的二进制文件。最新版本还增加了一个认证和授权插件 “mosquitto-go-auth”,以及一个用于管理 Mosquitto 实例的 Web 用户界面。此外,它还提供了一个 PHP 包装器 “Mosquitto-PHP”,可以方便地在 PHP 中开发 MQTT 客户端。

Eclipse Mosquitto 官方网站

GitHub - eclipse-mosquitto/mosquitto: Eclipse Mosquitto - An open source MQTT broker github开源网站

Mosquitto 服务器安装

1.下载 openssl 加密库源码

Old 1.1.1 Releases | OpenSSL Library

2.下载cjson 源码

GitHub - DaveGamble/cJSON: Ultralightweight JSON parser in ANSI C

3.下载mosquitto 服务器

Index of /files/source/

4.配置&安装⭐⭐

将下载好文件放到一个自己知道的路径,然后用wsl打开解压到家目录。不要解压到共享文件里。

------- openssl加密库安装---------
tar  -xvf   openssl-1.1.1q.tar.gz   -C    ~/   #1.解压源码 
cd  ~/openssl-1.1.1q/                          #2.进入源码目录  
./config                                       #3.默认配置  make   test  -j12                             #4.编译测试代码与库文件sudo  make  install                           #5.安装  ------cjson库安装-------cp  cJSON-master.zip   ~/    #1.拷贝到家目录cd  ~/                       #2.进入家目录sudo apt install unzip       #3.安装解压工具 unzip  cJSON-master.zip      #4.解压json源码 cd  cJSON-master/            #5.进入json源码make                         #6.编译源码sudo  make install           #7.安装 -----安装mosquitto代理服务器-----
sudo  apt-get install   g++                     #1.安装g++编译器
tar  -xvf  mosquitto-2.0.9.tar.gz   -C   ~/     #2.解压到家目录  
cd  ~/mosquitto-2.0.9/                          #3.进入源码目录   
make                                            #4.编译  
sudo  make  install                             #5.安装 tip💡如果cjson库或ssl 库安装失败    
cJSON - for client JSON output support. Disable with make WITH_CJSON=no Auto detected with CMake.make WITH_CJSON=no   #去掉cjson openssl (libssl-dev on Debian based systems) - disable with make WITH_TLS=nomake WITH_TLS=no

测试成功如下

四、mosquitto 代理服务器使用

1、订阅与发布命令

 #拷贝库文件到系统库中 sudo  cp  /usr/local/lib/lib*   /lib#拷贝系统的配置文件 cp  /etc/mosquitto/mosquitto.conf.example   ./  //当前文件为自己写代码的文件里

2、修改端口

3、关闭防火墙

#开启代理服务器  尝试能不能行mosquitto  -c  ./mosquitto.conf.example#订阅主题   'test/topic' mosquitto_sub -t 'test/topic' -v#发布消息   mosquitto_pub -t 'test/topic' -m 'hello world'

4、发布端函数接口

将官方大的代码拷贝到自己写代码的文件里边看官方代码边写自己的代码。

//1初始化MQTT库,在调用任何函数之前必须要调用该函数 
int mosquitto_lib_init(void);
返回值:MOSQ_ERR_SUCCESS - on success.//2创建一个新的客户端
struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
id:客户端ID,如何为NULL ,系统自动分配一个ID,且clean_session参数必须为 true 
clean_session:  true   代理服务器在客户端断开后会清除数据 false  代理服务器在客户端断开后会保留数据 
obj:传递给回调函数的参数  
返回值:成功   客户端对象地址      失败    NULL //3连接MQTT服务器 
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
mosq:客户端对象  
host:服务器IP地址 
port:服务器端口号 👉1883 
keepalive:保持连续ping 包,设置一段时间后发送一个ping给服务器 
返回值: MOSQ_ERR_SUCCESS - on success.//4启动网络线程,不断处理网络数据   
int mosquitto_loop_start(struct mosquitto *mosq);
mosq:客户端对象  
返回值: MOSQ_ERR_SUCCESS - on success.//5⭐重点,难点 : 发布消息 
int mosquitto_publish(struct mosquitto *mosq, //客户端对象  int *mid,  //消息ID ,设置为 NULL 即可const char *topic, //👍发布的消息主题int payloadlen,   //发布消息长度   between 0 and 268,435,455.const void *payload, //发布的消息int qos,  //👍消息质量  0 ,1 , 2bool retain); //消息保留标记为  true 保留消息

qos 消息质量

MQTT(Message Queuing Telemetry Transport)协议定义了三种消息质量等级(QoS),以确保在不同场景下消息的可靠传输。
以下是三种QoS级别的详细说明:
1. QoS 0(At Most Once,最多一次)
特点:消息最多被传递一次,没有确认机制,消息可能会丢失或重复。
适用场景:适用于对消息完整性要求不高的场景,如天气更新、实时数据流、传感器数据等。在这些场景中,即使消息丢失或重复,也不会造成重大影响。
传输过程:发送方发送消息后,不等待接收方的确认,也不存储消息以进行重传。
2. QoS 1(At Least Once,至少一次)
特点:消息至少被传递一次,但可能会出现重复的消息。
适用场景:适用于对消息丢失敏感,但对重复不敏感的场景,如传感器数据、开关状态同步等。在这些场景中,确保消息到达比避免重复更重要。
传输过程:发送方发送消息后,会等待接收方的确认报文(PUBACK)。如果未收到确认,发送方会重传消息。接收方收到消息后,会发送PUBACK确认报文。
3. QoS 2(Exactly Once,仅一次)
特点:消息确保只传递一次,没有重复。这是最高级别的QoS,适用于对消息的完整性和顺序性要求非常高的场景。
适用场景:适用于金融交易、关键命令等场景,在这些场景中,消息的丢失或重复都是不可接受的。
传输过程:发送方和接收方通过四次握手过程(PUBREC、PUBREL、PUBCOMP)来确保消息只被接收一次。发送方发送消息后,等待接收方的PUBREC确认,然后发送PUBREL,最后等待接收方的PUBCOMP确认。
QoS级别的选择
QoS 0:适用于实时性要求高,但对数据丢失和重复容忍度较高的场景。
QoS 1:适用于需要确保消息至少被接收一次,但允许重复的场景。
QoS 2:适用于需要确保消息仅被接收一次,且对实时性要求不高的场景。
注意事项
网络条件:在网络条件较差的情况下,建议选择较低的QoS级别,以减少消息丢失的风险。
系统资源:QoS级别越高,传输过程的复杂程度和系统资源消耗也越大。
综上所述,根据具体的应用场景和需求选择合适的QoS级别,可以在确保消息可靠传输的同时,优化系统性能和资源利用率。

⭐⭐发布端代码例子:

#include <mosquitto.h> //⚠️声明MQTT库的接口
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main(int argc, char *argv[])
{// 1.初始化MQTT库mosquitto_lib_init();// 2.创建一个客户端struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);if (mosq == NULL){perror("创建客户端失败\n");return 1;}else{printf("创建客户成功\n");}// 3.连接服务器,超时设置为60秒int ret = mosquitto_connect(mosq, "127.0.0.1", 1883, 60);if (ret != MOSQ_ERR_SUCCESS){perror("连接服务器失败\n");return 1;}else{printf("连接服务器成功\n");}// 4.启动网络线程mosquitto_loop_start(mosq);while (1){printf("请输入发布的主题和消息\n");char topic[50] = {0};char payload[268] = {0};scanf("%s %s", topic, payload);int ret = mosquitto_publish(mosq, NULL, topic, strlen(payload), payload, 0, false);if (ret != MOSQ_ERR_SUCCESS){perror("发布消息失败\n");return 1;}else{printf("发布消息成功\n");}}mosquitto_destroy(mosq); //销毁对象mosquitto_lib_cleanup(); //清空函数库 
}

5、订阅端函数接口

//1.初始化MQTT库,在调用任何函数之前必须要调用该函数 
int mosquitto_lib_init(void);
返回值:MOSQ_ERR_SUCCESS - on success.//2。创建一个新的客户端
struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
id:客户端ID,如何为NULL ,系统自动分配一个ID,且clean_session参数必须为 true 
clean_session:  true   代理服务器在客户端断开后会清除数据 false  代理服务器在客户端断开后会保留数据 
obj:传递给回调函数的参数  
返回值:成功   客户端对象地址      失败    NULL //3.连接MQTT服务器 
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
mosq:客户端对象  
host:服务器IP地址 
port:服务器端口号 👉1883 
keepalive:保持连续ping 包,设置一段时间后发送一个ping给服务器 (超时时间)
返回值: MOSQ_ERR_SUCCESS - on success.//4.订阅主题  
int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos);
mosq:客户端对象
mid:消息ID,设置为NULL不关心
sub:👍需要订阅的主题 
qos:消息质量 0,1,2
返回值: MOSQ_ERR_SUCCESS - on success.//5.⭐重点,难点:设置消息回调函数,当订阅的主题有消息时,会调用该函数
void mosquitto_message_callback_set(struct mosquitto *mosq, 
void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *));
mosq:客户端对象
on_message:函数指针,指向一个回调函数如下👇
void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{/* This blindly prints the payload, but the payload can be anything so take care. */printf("%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
}
mosq:客户端对象 
obj:创建客户端时传递的参数 
msg:👍消息💡消息结构体 
struct mosquitto_message{int mid;      //发布消息id char *topic;  //主题void *payload; //消息 int payloadlen; //消息长度  int qos;        //通信质量 bool retain;    //保留消息标记
};6.循环接收消息   int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets);mosq:客户端对象   timeout:超时检测 ,设置 -1 永久等待    

订阅端代码例子:

#include <mosquitto.h> //⚠️声明MQTT库的接口
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{/* This blindly prints the payload, but the payload can be anything so take care. */printf("%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
}int main(int argc, char *argv[])
{// 1.初始化MQTT库mosquitto_lib_init();// 2.创建一个客户端struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);if (mosq == NULL){perror("创建客户端失败\n");return 1;}else{printf("创建客户成功\n");}// 3.连接服务器int ret = mosquitto_connect(mosq, "127.0.0.1", 1883, 60);if (ret != MOSQ_ERR_SUCCESS){perror("连接服务器失败\n");return 1;}else{printf("连接服务器成功\n");}// 4.订阅一个主题ret = mosquitto_subscribe(mosq, NULL, "test", 0);if (ret != MOSQ_ERR_SUCCESS){perror("订阅失败\n");return 1;}else{printf("订阅成功\n");}// 5.设置消息回调函数mosquitto_message_callback_set(mosq, on_message); // 设置接收消息回调函数// 6.循环接收消息mosquitto_loop_forever(mosq, -1, 1); // 一直循环接收数据mosquitto_destroy(mosq);mosquitto_lib_cleanup();return 0;
}

五、MQTTX 调试助手

公共测试服务器:免费的公共 MQTT 服务器 | EMQ

MQTTX 下载

安装

设置为简体中文

主题的订阅与发布调试

1.新建链接:服务器为你写代码的地址。

2.主题订阅:主题名字随便

3.主题发布,要跟代码的订阅一样。

4.实现MQTT远程通信

即在调试助手中(发送端)发送消息到阿里云(部署MQTT代理服务器)中,然后MQTT代理服务器转换到Ubuntu的终端中。

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

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

相关文章

数据结构与算法——链表OJ题详解(2)

文章目录 一、前言二、OJ续享2.1相交链表2.2环形链表12.2环形链表2 三、总结 一、前言 哦了兄弟们&#xff0c;咱们上次在详解链表OJ题的时候&#xff0c;有一部分OJ题呢up并没有整理完&#xff0c;这一个星期呢&#xff0c;up也是在不断的学习并且沉淀着&#xff0c;也是终于…

SQL Server AlwaysOn (SQL 查询数据详解及监控用途)

修正后的完整查询 SELECT ar.replica_server_name AS [副本名称],ar.availability_mode_desc AS [同步模式],DB_NAME(dbr.database_id) AS [数据库名称],dbr.database_state_desc AS [数据库状态],dbr.synchronization_state_desc AS [同步状态],dbr.synchronization_health_d…

力扣热题100刷题day63|49.字母异位词分组

目录 一、哈希表相关理论 二、思路 核心思路 三、相关题目 四、总结 一、哈希表相关理论 代码随想录刷题day15|&#xff08;哈希表篇&#xff09;242.有效的字母异位词、383.赎金信-CSDN博客 二、思路 首先&#xff0c;创建一个map集合&#xff0c;遍历字符串数组&…

爱普生可编程晶振SG8201CJ和SG8200CJ在胃镜机器人发挥重要作用

在医疗机器人技术高速发展的今天&#xff0c;胃镜机器人作为胃肠道疾病诊断与治疗的创新设备&#xff0c;正逐渐改变传统诊疗模式。其复杂精密的系统需要精准的时间同步与稳定的信号输出&#xff0c;胃镜机器人是一种先进的医疗设备&#xff0c;用于无创性地检查胃部疾病。与传…

Ubuntu22环境下,Docker部署阿里FunASR的gpu版本

番外: 随着deepseek的爆火,人工智能相关的开发变得异常火爆,相关的大模型开发很常见的agent智能体需要ASR语音识别的功能,阿里开源的FunASR几乎是把一个商业的项目放给我们使用了。那么我们项目中的生产环境怎么部署gpu版本的语音识别服务呢?经过跟deepseek的一上午的极限…

图解Java设计模式

1、设计模式面试题 2、设计模式的重要性 3、7大设计原则介绍 3.1、单一职责原则

transformers的 pipeline是什么:将模型加载、数据预处理、推理等步骤进行了封装

transformers的 pipeline是什么:将模型加载、数据预处理、推理等步骤进行了封装 pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=50 )pipeline :这是 transformers 库中一个非常实用的工具函数。它可以基于预训练模型快速构…

jmeter插件安装

1、下载 下载地址&#xff1a; Documentation :: JMeter-Plugins.org 然后复制到D:\apache-jmeter-5.6.3\lib\ext 复制后 2、重启jmeter 在菜单【选项】找到“Plugins Manager” 在 Plugins Manager 界面上&#xff0c;点击“Available Plugins”标签页&#xff0c;可以浏览所…

VSCode CMake调试CPP程序

文章目录 1 安装C与CMake插件2 配置CMakeLists.txt3 使用CMake编译调试3.1 编译3.2 调试 4 自定义构建调试参考 1 安装C与CMake插件 C插件 CMake插件 2 配置CMakeLists.txt 编写测试程序 #include<iostream>int main(int argc, char const *argv[]) {int a 1, b 2;i…

【前端】【css】flex布局详解

Flex 布局&#xff08;Flexible Box Layout&#xff0c;弹性盒子布局&#xff09;是 CSS3 中的一种布局模式&#xff0c;用于在容器中更高效地分配空间并对齐内容&#xff0c;即使它们的大小是动态未知的。它非常适用于响应式设计。 一、Flex 布局的基本概念 1. 启用 Flex 布局…

LEARNING DYNAMICS OF LLM FINETUNING【论文阅读笔记】

LEARNING DYNAMICS OF LLM FINETUNING 一句话总结 作者将LLM的学习动力机制拆解成AKG三项&#xff0c;并分别观察了SFT和DPO训练过程中​​正梯度信号​​和​​负梯度信号​​的变化及其带来的影响&#xff0c;并得到以下结论&#xff1a; ​​SFT通过梯度相似性间接提升无关…

Mac 下载 PicGo 的踩坑指南

Mac 下载 PicGo 的踩坑指南 一、安装问题 下载地址&#xff1a;https://github.com/Molunerfinn/PicGo/releases 下载之后直接安装即可&#xff0c;此时打开会报错&#xff1a;Picgo.app 文件已损坏&#xff0c;您应该将它移到废纸篓。 这是因为 macOS 为了保护用户不受恶意…

Element UI 设置 el-table-column 宽度 width 为百分比无效

问题描述&#xff1a; 想要每列宽度不同&#xff0c;不想使用 px 固定值&#xff0c;将 width 设置成百分比&#xff0c;但是每一列还是很窄 原因&#xff1a; el-table 组件会被 vue 解析成 html&#xff0c;vue 直接把百分号去掉把数值当做列宽来呈现&#xff0c;所以&#x…

第五篇:Python面向对象编程(OOP)深度教程

1. 类与对象 1.1 基本概念 ​​类​​是创建对象的蓝图,定义了对象的​​属性​​(数据)和​​方法​​(行为)。​​对象​​是类的实例化实体,每个对象拥有独立的属性值和共享的类方法 ​​示例​​:定义Dog类 class Dog:species = "Canis familiaris" …

【数据结构】2.顺序表实现通讯录

文章目录 一、通讯录的要求二、通讯录的具体实现0、 准备工作1、通讯录的初始化2、通讯录的销毁3、通讯录的展示4、通讯录添加数据5、通讯录删除数据6、通讯录的查找7、通讯录的修改8、保存通讯录数据到文件9、读取文件内容到通讯录 三、 通讯录的完整实现 一、通讯录的要求 通…

程序化广告行业(79/89):技术革新与行业发展脉络梳理

程序化广告行业&#xff08;79/89&#xff09;&#xff1a;技术革新与行业发展脉络梳理 大家好&#xff01;一直以来&#xff0c;我都热衷于在技术领域不断探索&#xff0c;也深知知识共享对于进步的重要性。写这篇博客&#xff0c;就是希望能和大家一起深入研究程序化广告行业…

【C++游戏引擎开发】第9篇:数学计算库GLM(线性代数)、CGAL(几何计算)的安装与使用指南

写在前面 两天都没手搓实现可用的凸包生成算法相关的代码&#xff0c;自觉无法手搓相关数学库&#xff0c;遂改为使用成熟数学库。 一、GLM库安装与介绍 1.1 vcpkg安装GLM 跨平台C包管理利器vcpkg完全指南 在PowerShell中执行命令&#xff1a; vcpkg install glm# 集成到系…

python文件打包无法导入ultralytics模块

&#x1f4a5;打包的 .exe 闪退了&#xff1f;别慌&#xff01;教你逐步排查 PyInstaller 打包的所有错误&#xff01; &#x1f6e0; 运行 .exe 查看报错信息✅ 正确姿势&#xff1a; ⚠ importlib 动态导入导致打包失败❓什么是动态导入&#xff1f;✅ 解决方式&#xff1a; …

【React框架】什么是 Vite?如何使用vite自动生成react的目录?

什么是 Vite&#xff1f; Vite 是一个基于原生 ES Modules 开发的前端构建工具&#xff0c;由 Evan You&#xff08;Vue 的作者&#xff09;开发。它最大的特点包括&#xff1a; 极速冷启动&#xff1a;因为利用了浏览器原生的 ES Modules&#xff0c;所以在开发时无需等待整…

深入解读 React 纯组件(PureComponent)

什么是纯组件&#xff1f; React 的纯组件(PureComponent)是 React.Component 的一个变体&#xff0c;它通过浅比较(shallow comparison)props 和 state 来自动实现 shouldComponentUpdate() 方法&#xff0c;从而优化性能。 核心特点 1. 自动浅比较&#xff1a; PureCompon…