一、MQTT概述
1.什么是MQTT
MQTT是一种基于“发布订阅“”模式的消息传输协议。
消息:设备和设备之间传输的数据,或者服务和服务之间要传输的数据。
协议:传输数据时所遵循的规范。
2.常见的通讯模式
(1)客户端-服务器端:客户端和服务器端需要直接建立连接
(2)发布订阅模式:发布者和订阅者不需要直接建立连接
将发布者和订阅者进行隔离:
①.空间上的隔离。
②.时间上的隔离。
3.MQTT的特点
(1)轻量级:MQTT协议占用的系统资源较少,数据报文较少。
(2)可靠性较强:提供了多种消息的质量等级。
(3)安全性较强:提供传输层和套阶层加密功能
(4)双向通信:MQTT客户端既可以发送数据,也可以从代理软件中获取数据
(5)多语言支持: PHP、Node.js、Python、Golang、、java
因为这些特点,MQTT协议常用在物联网行业。
4.MQTT的常见概念
(1)MQTT的客户端
任何运行MQTT客户端库(MQTT开发工具包)的应用都是MQTT客户端。
(2)MQTT Broker
实现MQTT通讯软件的代理软件。
(3)主题
存在于MQTT Broker中的,一个普通的字符串,使用主题来对消息进行分类的。
二、MQTT快速入门
1.常用的代理软件 Broker
2. Windows安装EMQX
(1)下载EMQX
5.3.2版本以后就没有提供Windows系统软件包
5.3.2版本下载地址: https://www.emqx.com/zh/downloads/broker/v5.3.2
(2)创建EMQX文件夹,解压文件
解压后的目录如下:
(3)启动EMQX
进入bin文件夹,执行cmd
输入启动命令
emqx start
(4)配置文件
需在 EMQX 安装目录下的 etc 文件夹中的 emqx.conf 文件添加 listeners.tcp 配置项。
例如,若要启用端口 1883 上的 TCP 监听器,并设置监听器最多允许 1,024,000 个并发连接,可使用以下配置:
listeners.tcp.default {
bind = "0.0.0.0:1883"
max_connections = 1024000
}
配置说明:
listeners.tcp.default 代表启用该监听器,default 为监听器名称,可根据需要更改。
bind 设定监听器的 IP 地址及端口,此处配置为监听所有 IP 地址上的 1883 端口的所有传入流量。
max_connections 设置监听器允许的最大并发连接数,默认值为 infinity。
3.访问EMQX Dashborad
(1)服务启动后访问18083端口
本地的地址:http://localhost:18083/
账号:admin
密码:public
这里我在虚拟机里部署的EMQX,查看虚拟机IP地址+":18083"端口也可以。
默认网络端口:
SSL监听端口:8883
TCP监听端口:1883
WebSocker 监听端口:8083
WebSocket Secure 监听端口 :8084
4.修改密码
进入bin目录cmd,以用户admin密码改成"xxxxxxxx"举例:
emqx_ctl admins passwd admin xxxxxxxx
5.EMQX客户端
(1)MQTTX简介
MQTTX是一款由EMQ开源的跨平台MQTT 5.0客户端工具,它为开发人员提供了便捷的方式来测试、调试和探索MQTT连接。MQTT是一种轻量级的消息传输协议,特别适用于物联网设备和低带宽、高延迟或不稳定网络环境。
MQTTX 包含三种类型的工具:桌面客户端、命令行客户端、浏览器客户端。
官网地址:https://mqttx.app/zh
(2)MQTTX Desktop的使用
①下载并安装 MQTTX Desktop
下载地址:https://mqttx.app/zh/downloads
②新建发布链接
点击连接后,回到EMQX Dashborad ,客户端,可以看到这个连接
③新建消息接收连接
建立步骤一样,连接名字自己区分两个哪个是发布哪个是接受就行.
连接后回Dashborad刷新验证一下是不是两个连接了
④添加订阅信息
回到MQTTX接收信息的连接,点击添加订阅
Topic换成我们真实要订阅的主题就行
回到Dashboard查看订阅信息
④信息发布
我们在MQTTX的发布信息连接里,编辑信息,首先编辑主题名,然后编辑发布的信息,最后点发布
点完发布后,我们回到信息接受连接,可以看到信息已经接收到了
(3)命令行客户端的使用
①下载命令行客户端工具
②使用命令行客户端订阅
下载后放到一个没中文的单独的文件夹,在该目录cmd
命令;
mqttx-cli-win-x64.exe sub -t 'test02' -h 192.168.163.129 -p 1883 -v
mqttx-cli-win-x64.exe -> 指定命令行客户端
sub -> 订阅主题
-t 'test02' -> -t 代表订阅的主题 引号里放实际订阅的主题
-h 192.168.163.129 -> -h broker的访问地址 后面跟实际地址
-p 1883 -> -p 指定broker访问端口号 后面跟实际业务端口
-v -> 一旦订阅的主题发布信息,要将这个信息打印出来
输入命令回车,打印出下图结果证明建立了连接,并且订阅了主题
③使用命令行客户端发布信息
再在该目录创建个cmd窗口,输入命令
mqttx-cli-win-x64.exe pub -t 'test02' -q 0 -h 192.168.163.129 -p 1883 -m "from MQTTX CLI"
pub -> 发布信息
-t -> 要往哪个主题里发
-q 0 -> 指定发布消息的质量等级
-m -> 指定发布的消息
输入命令后回车,打印下面信息代表发布出去了
再看接受的黑窗口,显示下面信息,证明接收到信息了
(4)浏览器客户端工具
在线地址:https://mqttx.app/web-client#/recent_connections
也可以私有化到自己的服务器
MQTTX想要私有化部署的用户提供了 Docker 镜像,可以通过以下命令快速部署,也可以参考开发指南,自行构建后部署。
docker pull emqx/mqttx-web
docker run -d --name mqttx-web -p 80:80 emqx/mqttx-web
三、MQTT控制报文
1.报文简介
报文是网络中交换与传输的数据最小单元,通俗来讲就是站点一次性要发送的数据块。它包含了将要发送的完整数据信息,其长短不一致,长度不限目可变。MQTT 客户端和服务端通过交换控制报文来完成它们的工作,比如订阅主题和发布消息。
2.常见的控制报文
MQTT 目前定义了 15 种控制报文类型,如果按照功能进行分类,我们可以将这些报文分为连接、发布、订阅三个类别:
3.MQTT报文格式
在 MQTT 中,无论是什么类型的控制报文,它们都由固定报头、可变报头和有效载荷三个部分组成。
固定报头固定存在于所有控制报文中,而可变报头和有效载荷是否存在以及它们的内容则取决于具体的报文类型。例如用于维持连接的 PINGREQ 报文就只有一个固定报头,用于传递应用消息的 PUBLISH 报文则完整地包含了这三个部分。
(1)固定报头
固定报头由报文类型、标识位和报文剩余长度三个字段组成。
①报文类型
占4个bit位,是一个无符号的整数
常见的报文类型:https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901022
②标识位
占4个bit位,不过到 MQTT5.0 为止,只有 PUBLISH 报文的这四个比特位被赋予了明确的含义:
1、Bit 3:DUP,表示当前 PUBLISH 报文是否是一个重传的报文。
2、Bit 2,1:QoS,表示当前 PUBLISH 报文使用的服务质量等级。
3、Bit 0:Retain,表示当前 PUBLISH 报文是否是一个保留消息。
其他所有的报文中,这 4位都仍是保留的。
③剩余长度
剩余长度指示了当前控制报文剩余部分的字节数,也就是可变报头和有效载荷这两个部分的长度。MQTT 控制报文的总长度= 固定报头的长度 + 剩余长度。
(2)可变报头
可变报头的内容取决于具体的报文类型
举例:
1、CONNECT 报文的可变报头按顺序包含了协议名、协议级别、连接标识、Keep Alive 和屋性这五个字段
2、PUBLISH 报文的可变报头则按顺序包含了主题名、报文标识符和屋性这三个字段。
犀件是 MOTT5.0引入的一个概念。屌性字段基本上都是可变报头的最后一部分,由犀性长度和紧随其后的一组属性组成,这里的屋性长度指的是后面所有属性的总长度
所有的属性都是可选的,因为它们通常都有一个默认值,如果没有任何属性,那么属性长度的值就为0。属性通常都是为了某个专门的用途而设计的,不同的报文所支持的,
性都是不一样的,具体的对应情况可以查看官网地址:https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901027
(3)有效载荷
有效载荷是用于实现对应报文的核心功能。
举例:
1、在 PUBLISH 报文中,Payload 用于承载具体的应用消息内容,这也是 PUBLISH 报文最核心的功能。
2、在 SUBSCRIBE 报文中,Payload 包含了想要订阅的主题以及对应的订阅选项,这也是 SUBSCRIBE 报文最主要的工作。
(4)报文验证
接下来我们通过Wireshark工具,抓取一下各种通讯操作所涉及到的报文。
下载地址:https://www.wireshark.org/download.html
四、QOS消息的质量等级
1.QOS常见的取值
0: 消息最多发送一次 --> 可能导致信息的丢失
1: 消息至少发送一次 --> 肯定不会出现数据的丢失,消息可能会重复
2:消息仅有一次发送 --> 消息肯定不会丢失,消息也不会重复
在发送消息的时候可以指定消息的质量等级,一般情况下broker获得消息以后,会按照发送时消息指定的质量等级发给订阅者。特殊情况下,消息登记可能发生改变,当订阅者指定了订阅时消息的最大的质量等级,消息质量等级可能发生改变。
2.QOS通讯原理
(1)QoS 0 原理
QoS 0 是最低的 QoS 等级。QoS 0 消息即发即弃,不需要等待确认,不需要存储和重传,因此对于接收方来说,永远都不需要担心收到重复的消息。
(2)QoS 1 原理
QoS 1 引用了应答和重传机制
对于发送方来说,没收到 PUBACK 报文分为以下两种情况:
1、PUBLISH 未到达接收方
2、PUBLISH 已经到达接收方,接收方的PUBACK报文还未到达发送方在第一种情况下,发送方虽然重传了 PUBLISH 报文,但是对于接收方来说,实际上仍然仅收到了一次消息在第二种情况下,在发送方重传时,接收方已经收到过了这个PUBLISH 报文,这就导致接收方将收到重复的消息
(3)QoS 2 原理
看了很多的网上的概念一直没懂,为什么"Qos 2是如何保证只收到一次的?"
后来查阅很多资料,说下我自己的理解:QoS 2 的本质是通过 “发布者→代理服务器”,“代理服务器→订阅者” 两条链路的双重确认机制,确保消息在任何网络波动下都不会被重复处理。三者类似,发件人、快递站、收件人三者的关系,每条信息有唯一的“报文ID”类似快递单号,用于识别重复消息。
那下面讲讲第一条链路的流程: