Linux--MQTT(二)通信基本原理

news2024/11/26 2:49:44

一、MQTT 通信基本原理

MQTT 是一种基于 客户端 - 服务端 架构的消息传输协议,所以在 MQTT 协议通信中,有两个最为重要的角色,它们便是服务端 客户端
举例:若开发板向“芯片温度”这一主题发布消息,那么服务端接收到消息后会将消息转发给订阅了“芯片温度”的所有客户端。

服务端

MQTT 服务端通常是一台服务器( broker ),它是 MQTT 信息传输的枢纽,负责将 MQTT 客户端发送来的信息传递给 MQTT 客户端; MQTT 服务端还负责管理 MQTT 客户端,以确保客户端之间的通讯顺畅, 保证 MQTT 信息得以正确接收和准确投递。

客户端

MQTT 客户端可以向服务端发布信息,也可以从服务端收取信息;我们把客户端发送信息的行为称为 “发布”信息。而客户端要想从服务端收取信息,则首先要向服务端“订阅”信息。“订阅”信息这一操作很像我们在使用微信时“关注”了某个公众号,当公众号的作者发布新的文章时,微信官方会向关注了该公众号的所有用户发送信息,告诉他们有新文章更新了,以便用户查看。

MQTT 主题

客户端想要从服务器获取信息,首先需要订阅信息,那客户端如何订阅信息呢?这里我们要引入“主题(Topic )”的概念,“主题”在 MQTT 通信中是一个非常重要的概念,客户端发布信息以及订阅信息都是围绕“主题”来进行的,并且 MQTT 服务端在管理 MQTT 信息时,也是使用“主题”来控制的。
客户端发布消息时需要为消息指定一个“主题”,表示将消息发布到该主题;而对于订阅消息的客户端来说,可通过订阅“主题”来订阅消息,这样当其它客户端或自己(当前客户端)向该主题发布消息时,MQTT 服务端就会将该主题的信息发送给该主题的订阅者(客户端)。
值得注意的是, MQTT 客户端在通信时,角色往往不是单一的,一个客户端既可以作为信息发布者也可以同时作为信息订阅者。如下图所示:

MQTT 发布/订阅特性

MQTT 通信的核心枢纽是 MQTT 服务端,它负责将 MQTT 客户端发送来的 信息传递给 MQTT 客户端,还负责管理 MQTT 客户端,以确保客户端之间的通讯顺畅,保证 MQTT 信息得以正确接收和准确投递。
客户端相互独立: MQTT 客户端是一个个独立的个体,它们无需了解彼此的存在,依然可以实现 信息交流。
时间上可异步: MQTT 客户端在发送和接收信息时无需同步。这一特点对物联网设备尤为重要, 前面我们也介绍了,MQTT 从诞生之初就是专为低带宽、高延迟或不可靠的网络而设计的,高延 迟和不可靠网络必然就会导致时间上的异步;物联网设备在运行过程中发生意外掉线是非常正常 的情况,我们使用上面的实例二的场景来作说明,当开发板在运行过程中,可能会由于突然断电 (假设开发板是通过电源适配器供电的)导致掉线,这时开发板会断开与 MQTT 服务端的连接。 假设此时我们的手机客户端向开发板客户端所订阅的“LED 控制”主题发布了信息,而开发板恰 恰不在线,这时,MQTT 服务端可以将“ LED 控制”主题的新信息保存,待开发板客户端再次上线后,服务端再将“LED 控制”信息推送给开发板。所以这就必然导致了,手机发送信息与开发板接收信息在时间上是异步的。

二、连接MQTT服务端

MQTT 客户端之间想要实现通信,必须要通过 MQTT 服务端。所以,客户端无论是发布信息还是订阅信息都必须先连接到服务端。下面我们来看一下,客户端连接服务端的详细过程。

MQTT 客户端连接服务端总共包含了两个步骤:

①、首先客户端需要向服务端发送连接请求,这个连接请求实际上就是向服务端发送一个 CONNECT报文,也就是发送了一个 CONNECT 数据包。
②、 MQTT 服务端收到连接请求后,会向客户端发送连接确认。连接确认实际上是向客户端发送一个CONNACK 报文,也就是 CONNACK 数据包。

CONNECT 报文

在上面的描述中我们看到, MQTT 客户端要想连接服务端,首先要向服务端发送 CONNECT 报文。如 果此 CONNECT 报文的格式或内容不符合 MQTT 规范,则服务器会拒绝客户端的连接请求。
一个CONNECK报文内容举例如下:
                 
所谓报文就是一个数据包, MQTT 报文组成分为三个部分:固定头( Fixed header )、可变头( Variable header)以及有效载荷( Payload ,消息体)。这里我们简单地介绍一下:
固定头( Fixed header ): 存在于所有 MQTT 报文中,固定头中有报文类型标识,可用于识别是哪 种 MQTT 报文,譬如该报文是 CONNECT 报文还是 CONNACK 报文,亦或是其它类型报文。
可变头( Variable header ): 存在于部分类型的 MQTT 报文中,报文的类型决定了可变头是否存 在及其具体的内容。
消息体( Payload ): 存在于部分类型的 MQTT 报文中, payload 就是消息载体的意思。
在上图中的报文内容有:
clientId-- 客户端 id
clientId MQTT 客户端的标识,也就是 MQTT 客户端的名字, MQTT 服务端可通过 clientId 来区分不同的客户端,MQTT 服务端用该标识来识别客户端。
keepAlive-- 心跳时间间隔
keepAlive 其实是指定了心跳时间间隔,也就是客户端向服务端发送心跳包的时间间隔。譬如 keepAlive=60 ,表示告诉服务端,客户端将会每隔 60 秒左右向服务端发送心跳包。
cleanSession-- 清除会话
cleanSession 设置为 1 ,表示此次连接将创建一个新的临时会话,在客户端断开后,这个会话会自动销毁。而 cleanSession 设置为 0 ,表示创建一个持久性会话,在客户端断开连接时,会话仍然保持并保存离线消息,直到会话超时注销。

CONNACK 报文

                  

returnCode-- 连接返回码
当服务端收到了客户端的连接请求后,会向客户端发送 returnCode( 连接返回码 ) ,用来说明连接情况。 如果客户端与服务端成功连接,则返回数字“0 ”。如果未能成功连接,返回码将会是一个非零的数字。
sessionPresent
CONNACK 报文的 sessionPresent CONNECT 报文的 cleanSession 相互配合。其作用是客户端发送连接请求时,服务端告知客户端有没有保存会话状态。这个被服务端保存的会话状态是来自于上一 次客户端连接时,譬如离线消息以及上一次连接时客户端所订阅的主题。

三、断开连接

MQTT 客户端连接到服务端之后,在后续的通信过程中,如果客户端想要断开与服务端的连接,此 时客户端可以主动向服务端发送一个 DISCONNECT 报文来断开与服务端的连接,如下图所示:
         

四、发布消息、订阅主题与取消订阅主题

当客户端连接到服务端之后,便可以发布消息或订阅主题了。

PUBLISH–发布消息

当客户端连接到服务端之后,就可以向服务端发布消息了,每条发布的消息必须指定一个“主题”,表示向某主题发布消息;MQTT 服务端可以通过主题来确定将消息转发给哪些客户端(订阅了该主题的客户端)。
MQTT 客户端向服务端发布消息其实就是向服务端发送一个 PUBLISH 报文,服务端收到客户端发送过来的 PUBLISH 报文之后,会向发送方回复一个报文。根据 QoS 的不同,回复的报文类型也是不同的,并且 整个发布消息的过程也将会有所区别;譬如对于 QoS=1 时,客户端向服务端发送 PUBLISH 报文,服务端 收到 PUBLISH 报文之后会向发送方回复 PUBACK 报文;而对于 QoS=2 的情况,将会更加复杂。
下图是 PUBLISH 报文包含的信息:
               
packetId-- 报文标识符
报文标识符可用于对 MQTT 报文进行标识(识别不同的报文)。不同的 MQTT 报文所拥有的标识符不同。MQTT 设备可以通过该标识符对 MQTT 报文进行甄别和管理, MQTT 协议内部使用的标识符。请注意:
报文标识符的内容与 QoS 级别有密不可分的关系。只有 QoS 级别大于 0 时,报文标识符才是非零数值。如果 QoS 等于 0 ,报文标识符为 0
topicName-- 主题名字
这个就是发布消息时对应的主题的名字,这是一个字符串,譬如上图中 topicName= myTopic ”,表示会将消息发布到“myTopic ”这个主题。
payload-- 有效载荷
有效载荷是我们希望通过 MQTT 所发送的实际内容。我们可以使用 MQTT 协议发送字符串文本,图像等格式的内容。这些内容都是通过有效载荷所发送的。
qos-- 服务质量等级
QoS Quality of Service )表示 MQTT 消息的服务质量等级。 QoS 有三个级别: 0 1 2 QoS 决定 MQTT 通信有什么样的服务保证。
retain-- 保留标志
在默认情况下,当客户端订阅了某一主题后,并不会马上接收到该主题的信息。因为客户端订阅该主题 之后,并没有其它客户端向该主题发布消息;只有在客户端订阅该主题后,服务端接收到该主题的新消息时,服务端才会将最新接收到的该主题消息推送给客户端。
但是在有些情况下,我们需要客户端在订阅了某一主题后马上接收到一条该主题的信息。这时候就需要用到保留标志这一信息。
dup-- 重发标志
dup 标志指示此消息是否重复。
MQTT 报文的接收方没有及时向报文发送发回复 确认收到报文 时,发送方会以为对方没有收到信息,会再次重复发送 MQTT 报文(譬如客户端向服务端发送 PUBLISH 报文,服务端收到 PUBLISH 报文之后需要向客户端回复一个 PUBACK 报文,如果客户端没收到 PUBACK 报文,则会认为服务端可能没接收到自己发送的报文,将会再次发送 PUBLISH 报文)。在重复发送 MQTT 报文时,发送方会将此“dup--重发标志”设置为 true 请注意,重发标志只在 QoS 级别大于 0 时使用。

SUBSCRIBE--订阅主题

客户端要想接收消息,首先要订阅该消息的主题。这样,当有客户端向该主题发布消息后,订阅了该主题的客户端就能接收到消息了。
客户端要想订阅主题,首先要向服务端发送主题订阅请求。客户端是通过向服务端发送 SUBSCRIBE 报文来实现这一请求的。该报文包含有一系列“订阅主题名”。请留意,一个 SUBSCRIBE 报文可以包含有单个或者多个订阅主题名。也就是说,一个 SUBSCRIBE 报文可以用于订阅一个或者多个主题。服务端会根据 SUBSCRIBE 中的 QoS 来提供相应的服务保证。
  
SUBACK 报文包含有“订阅返回码”和“报文标识符”这两个信息。
returnCode-- 订阅返回码
客户端向服务端发送订阅请求后,服务端会给客户端返回一个订阅返回码。在之前的讲解中我们说过,客户端可通过一个 SUBSCRIBE 报文发送多个主题的订阅请求。服务端会针对 SUBSCRIBE 报文中的所有订阅主题来逐一回复给客户端一个返回码。这个返回码的作用是告知客户端是否成功订阅了主题。
           

UNSUBSCRIBE--取消订阅主题

客户端订阅了某一主题之后,可以随时取消订阅, MQTT 协议提供了这样的操作。
客户端通过向服务端发送一个 UNSUBSCRIBE 报文来取消订阅主题,当服务端接收到 UNSUBSCRIBE报文后,会向发送发回复一个 UNSUBACK 报文(取消订阅确认报文),如下图所示:

五、主题的进阶

主题的基本形式就是一个字符串,譬如: "myTopic" "currentTemp" "LEDControl"等,但是有几个点需要大家注意一下:

1、主题形式

主题是区分大小写的。 所以 "LEDControl" "ledControl" 是两个不同的主题。
主题可以使用空格。 譬如 "LED Control" ,虽然主题允许使用空格,但是笔者建议大家尽量不要使用空格。
不要使用中文主题。 虽然有些 MQTT 服务器支持中文主题,但是绝大部分 MQTT 服务器是不支持中文主题的,所以大家不要使用中文主题,而是使用 ASCII 字符来作为 MQTT 主题。

2、主题分级

MQTT 主题可以是一个简单的字符串,譬如: "myTopic" "currentTemp" "LEDControl" ,事实上, MQTT协议为了更好的对主题进行管理和分类,支持主题分级,对主题进行分级处理,各个级别之间使用" / " 符号进行分隔。如下所示:
"home/sensor/led/brightness"
在以上示例中一共有四级主题,分别是第 1 home 、第 2 sensor 、第三级 led 、第 4 brightness 。 主题的每一级至少需要一个字符;而只有一个简单字符串的主题,如"myTopic" "currentTemp"、 "LEDControl",这些都是单一级别的主题。需要注意的是,主题名称不要使用 " / " 开头。

3、主题通配符

当客户端订阅主题时,可以使用通配符同时订阅多个主题。通配符只能在订阅主题时使用,分为单级通配符和多级通配符。

4、主题应用注意事项

$ 开头的主题
$ 号开头的主题是 MQTT 服务端系统保留的特殊主题,客户端不可随意订阅或向其发布信息
不要使用“ / ”作为主题开头
尽量不要使用“ / ”作为主题的开头,这样做没有什么意义,而且额外产生一个没有用处的主题级别。
主题中不要使用空格
虽然, MQTT 支持在主题中使用空格,但是我们应该尽量避免使用空格。
保持主题简洁明了
MQTT 是一种轻量级的通讯协议,它常用于网络带宽受限的环境,因此我们应尽量让主题简洁明了,从而让设备间交互的内容更加简洁,以更好的适应网络带宽受限的环境。
主题中尽量使用 ASCII 字符
虽然有些 MQTT 设备支持 UTF-8 字符作为 MQTT 主题,建议在主题中尽量使用 ASCII 字符。

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

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

相关文章

【Better Lighting V2】Blender商城10周年免费送插件灯光预设和图案轮库场景打光和模拟光透过图案水滴波纹效果

Blender商城10周年免费送插件:https://blendermarket.com/birthday Better Lighting V2 灯光预设和图案轮库 模拟各种环境下光线透过物体效果 各种预设快速调整 非常简单和快速打光调色 更多详细介绍:https://blendermarket.com/products/bette…

前端老古董execCommand——操作 选中文本 样式

文章目录 ⭐前言⭐exe command api用法💖 example示例💖 测试效果 ⭐execommand和getSelection 的联系⭐总结⭐结束 ⭐前言 大家好,我是yma16,本文分享关于 前端老古董execCommand——操作选中文本。 execommand 当一个 HTML 文…

Spring的事务步骤

一、事务处理方案: Spring框架中提供的事务处理方案:一共有两种: 适合中小项目使用的, 注解方案: 注解的方式做事务用起来简单,灵活,方便,中小型项目中用它比较方便,因…

关于二分法的理解(以JS为例)

算法介绍 基本概念 二分查找算法,又称折半查找算法,是一种在有序数组中查找特定元素的高效方法。它的核心思想是将数组分成两半,然后根据目标值与中间元素的比较结果来决定是继续在左半部分还是右半部分进行搜索。 工作原理 初始化&#…

编译安装qemu-devel @FreeBSD

缘起 使用cbsd创建riscv jail的时候提示: you have no qemu-user, please install qemu-devle with BSD_USER and STATIC ops (emulators/qemu-devel) 使用pkg安装之后,创建的riscv jail启动报错: Starting jail: fbriscv, parallel timeo…

【猫狗分类】Pytorch VGG16 实现猫狗分类2-模型构建

背景 数据处理做好了,现在搭建网络 声明:整个数据和代码来自于b站,链接:使用pytorch框架手把手教你利用VGG16网络编写猫狗分类程序_哔哩哔哩_bilibili 我做了复现,并且记录了自己在做这个项目分类时候,一…

【回文 马拉车】214. 最短回文串

本文涉及知识点 回文 马拉车 LeetCode214. 最短回文串 给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。 示例 1: 输入:s “aacecaaa” 输出:“aaacecaaa” 示…

string类的使用手册

1.构造函数 补充:npos:size_t类型数据的最大值 default (1) string(); 构造空的string类对象 copy (2) string (const string& str); 拷贝构造函数(深拷贝) substring (3) string (const string& str, size_t pos, size_…

python 实现各种数据分析方法

1、相关性分析 1.1、https://zhuanlan.zhihu.com/p/669355778https://zhuanlan.zhihu.com/p/669355778

【AI学习】Together AI的新研究:Together MoA(Mixture of Agents)

第一次听说Mixture of Agents,原来Agent也能混合,有意思! 介绍 Together AI的最新研究“Together MoA”(Mixture of Agents,代理混合)是一种创新的方法,旨在通过结合多个开源大型语言模型&…

Postman使用教程(Postman详细图文教程)

本文讲解的是postman工具安装、postman安装教程、postman工具下载、postman使用教程。Postman使得得开发人员和测试人员能够更高效地与Web服务进行交互和调试。 Postman不仅支持常见的HTTP方法,如GET、POST、PUT、DELETE等,还提供了丰富的请求编辑功能&…

Linux---防火墙

文章目录 目录 文章目录 前言 一.静态防火墙:iptables iptables五链 iptables 四表 iptables控制类型 iptables命令配置 前言 这儿主要介绍Linux系统本身提供的软件防火墙的功能,即数据包过滤机制。 数据包过滤,也就是分析进入主机的网络数…

Ubuntu20.04配置ORBSLAM2并在kitti数据集序列进行实验

一、ORB-SLAM2 安装和编译 1.ORB-SLAM2下载 用以下命令在终端上下载 git clone https://github.com/raulmur/ORB_SLAM2 2.安装Pangolin 在下载了ZIP压缩包后解压缩放在ubantu的/home下(此处只要是英文路径都可以),但别急着安装Pangolin我…

STM32项目分享:智慧农业(机智云)系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板打样焊接图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片: 哔哩哔哩视频链接: https://www.bilibili.c…

PCIe总线-RK3588 PCIe子系统简介(八)

1.PCIe子系统 RK3588 PCIe子系统如下图所示。总共拥有5个PCIe控制器。PCIe30X4(4L)支持RC和EP模式,其他4个仅支持RC模式。ITS port 1连接PCIe30X4(4L)和PCIe30X2(2L)控制器,PCIe30X4(4L)和PCIe30X2(2L)控制器使用PCIe3.0 PIPE PHY。ITS port 0连接PCIe3…

mysql:简单理解mysql mvcc的可重复读

# 原理 假设有这样的sql begin select(或update、insert、delete) ... commit当执行【begin】的时候,标记有一个新事务要开始,但是事务还没有真正开始,事务id还没有产生当执行事务里面的第一个sql语句时(…

VCG显示——汉字,数字,图像

详细的介绍资料: 【从零开始走进FPGA】 玩转VGA http://www.cnblogs.com/spartan/archive/2011/08/16/2140546.html 【FPGA实验】基于DE2-115平台的VGA显示_vga接口实验 de2-115-CSDN博客 【FPGA】VGA显示文字、彩条、图片——基于DE2-115-CSDN博客 一.VCG原理 1.1…

区块链中的gas与转账收款相关概念

区块链是一个经济系统 计算与存储系统都是稀缺的,区块链的工作需要消耗资源共识、trustless需要矿工的工作,而矿工需要激励Transaction的执行有成本(gas),gas费成为矿工的奖励ether是这个经济生态系统的通行货币 关心的问题 合…

Stable Diffusion vs DALL·E3

大模型技术论文不断,每个月总会新增上千篇。本专栏精选论文重点解读,主题还是围绕着行业实践和工程量产。若在某个环节出现卡点,可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技(Mamba,xLSTM,KAN)则提…

父亲节:我要做爸爸的健康监督员

父亲节将至,总想着能为爸爸做些什么,来表达我们的感激与关爱。在这个特殊的日子里,成为爸爸的健康监督员,用华为 Watch 4 的智慧健康功能,任何时刻都可以关注爸爸的健康状况,放心又安心了。 用一键微体检…