请点赞关注,你的反对对我意义重大。
🔥 Hi,我是小彭。本文已收录到 GitHub · AndroidFamily 中。这里有 Android 进阶成长常识体系,有气味相投的敌人,关注公众号 [彭旭锐] 带你建设外围竞争力。
前言
大家好,我是小彭。
MQTT 是一种基于公布 – 订阅模型的消息传递协定 ,在物联网和挪动利用有较宽泛的利用。如果你的指标是冲击中高级工程师岗位,MQTT 或者是一个不错的亮点。最近,我还发现很多候选人会在简历中写本人“相熟 MQTT 协定”,但少数人只是停留在理解或用过的水平。
这篇文章里,我将与你探讨 MQTT 协定的 工作原理 & 协定音讯格局 & 外围个性 ,实战的局部咱们会在下篇文章中探讨。如果能帮上忙,请务必点赞加关注,给小彭一点创作的能源。
记录:2022 年 9 月 9 日订正:优化文章构造
学习路线图:
1. 意识 MQTT
1.1 什么是 MQTT?
MQTT (Message Queuing Telemetry Transport,音讯队列遥测传输) 是一种基于 TCP/IP 协定族的应用层协定。MQTT 协定是专门针对硬件性能低下 & 网络情况不稳固的场景设计的,这使得 MQTT 在物联网和挪动利用等受限场景失去广泛应用。
1.2 MQTT 协定的倒退历史
- 1999 年:Andy Stanfork-Clark (IBM) 和 Arlen Nipper 公布 MQTT 协定,用于通过卫星连贯石油管道遥测零碎,MQTT 中的 TT (Telemetry Transport) 就是源于这样一个遥测零碎;
- 2010 年:MQTT 协定收费公布;
- 2014 年:MQTT 协定正式成为 OASIS 规范,通过多年的倒退,MQTT 协定曾经成为互联网 (IoT) 的次要协定之一。
目前,MQTT 次要分为两个大版本:
- MQTT v3: 其中 v3.1.1 是最罕用的版本,咱们的实战篇也是基于协定版本;
- MQTT v5: 2018 年公布,目前利用无限。
1.3 MQTT 协定的工作模型
MQTT 是基于公布 – 订阅模型 (pub/sub) 的消息传递协定,与申请 – 响应模型不同,公布 – 订阅模型次要有三种角色:publisher & subscriber & subscriber:
- publisher & subscriber (发布者 & 订阅者): 是指通过网络连接到 MQTT broker 的设施,也叫 客户端 (client)。一个客户端既能够作为音讯发布者,也能够作为音讯订阅者;
- broker (代理): 代理是整个公布 – 订阅模型的外围,也叫 服务端 。
当 client 公布某个主题的音讯时,broker 会将该音讯分发给任何已订阅该主题的 client。通常来说,client 不会存储音讯,一旦音讯被发送到这些 client,音讯就会从 broker 上删除。另外,保留音讯、长久连贯和服务质量 QoS 可能会导致音讯长期存储在 broker 上。
公布 – 订阅模式使得 音讯的发布者和订阅者解耦 ,次要体现为空间解耦和工夫解耦:
- 空间解耦 / 设施解耦: 发布者和订阅者通过 broker 进行消息传递,相互之间感知不到对方的存在。当一个客户端断线时,整个零碎能够持续工作;
- 工夫解耦: publisher 和 subscriber 不肯定须要同时运行;
图片援用自 https://juejin.cn/post/6976441705067184135 —— cxuan 著
1.4 MQTT 协定和 HTTP 协定有什么区别?
个性 | MQTT 协定 | HTTP 协定 |
---|---|---|
传输层 | TCP | TCP 或 UDP |
散发模型 | 公布 – 订阅模型 | 申请 – 响应模型 |
散发关系 | 1 对 0/1/N | 1 对 1 |
数据安全 | 应用 SSL/TLS | 不肯定采纳 HTTPS |
加密 | 应用层对有效载荷加密 | 不在应用层加密 |
音讯头大小 | 较小 | 较大 |
- 1、MQTT 协定基于传输层 TCP 协定,而 HTTP 能够基于 TCP 或 UDP(HTTP/3);
- 2、MQTT 协定采纳公布 – 订阅模型,同一个设施既能够是发布者也能够是订阅者;而 HTTP 协定采纳申请 – 响应模型,一个设施作为申请方,另一个设施作为响应方;
- 3、MQTT 音讯散发能够是 1 对 0/1/N,而 HTTP 音讯散发是 1 对 1;
- 4、MQTT 协定应用 SSL/TLS 来确保安全,而 HTTP 协定并不规定应用 HTTPS;
- 5、MQTT 协定在应用层对有效载荷 (payloads) 加密,而 HTTPS 协定不在应用层加密,在传输数据前不会加密数据;
- 6、MQTT 音讯头较小,而 HTTP 音讯头较大(HTTP/2 有头部压缩);
1.5 为什么 MQTT 协定适宜物联网和挪动利用场景?
物联网和挪动利用场景的特点是硬件性能低下和网络情况不稳固,而 MQTT 协定就是专门针对这种环境设计的,次要在四个方面有劣势:
- 1、架构设计: MQTT 协定采纳公布 – 订阅模型,使得音讯发布者和音讯订阅者相互解耦,当一个客户端断线时,整个零碎能够持续工作。这使得 MQTT 在网络品质的场景下更具劣势;
- 2、音讯大小: MQTT 协定具备十分小的音讯头,这使得 MQTT 协定更适应低带宽网络环境;
- 3、交付能力: MQTT 协定提供了更丰盛的音讯交付保障能力,它定义了三种音讯公布服务质量 (QoS):“最多发一次”、“起码发一次”和“正好发一次”。其中,“正好一次”用于计费零碎和 IM App 推送中,能确保用户收到且只收到一次;
- 4、间歇性连贯: MQTT 提供了遗嘱音讯和保留音讯的个性。遗嘱音讯使得客户端端断开连接时,所有订阅的客户端都能收到来自代理的音讯;保留音讯意味着新订阅的客户端能够立刻取得保留的音讯(相似粘性音讯)。这使得 MQTT 协定更适宜网络不稳固的 间歇性连贯的场景。
1.6 谁更适宜物联网(HTTP/2 & WebSocket & MQTT)?
- HTTP/2 是 HTTP/1.x 的降级,次要体现在:利用 “多路复用和二进制分帧” 来解决队首阻塞问题,升高了通信时延;利用 “头部压缩” 缩小音讯头部,升高了传输开销;实现了 服务器推送 ,容许在不发动申请的状况下将数据推送到客户端,补救了 Http/1.x 依赖 Websockets 能力实现推送的缺点。这些改良使得 HTTP/2 也具备适应物联网场景的条件;
- WebSockets 是在 Web 浏览器和 Web 服务器之间进行握手的协定,它升高了应用 Http/1.x 进行双工通信的开销。随着 HTTP/2 成为规范,对 websockets 的需要可能会降落;
- MQTT 是基于公布订阅模型的协定,因其带宽耗费小而被广泛应用于物联网协定。
论断:这三种协定并没有相对的优胜者,最好的协定取决于具体的需要和限度条件。但如果只从带宽、电池、性能多样性这些根本条件看,MQTT 在其中是更占优的抉择。例如,我司的 IM 产品在 App 端是采纳 MQTT 协定的实现,而在 Web 端因为有良好的 WebSocket 能力根底,所以采纳的是 WebSocket 传输 MQTT 格局音讯。
1.7 为什么 MQTT 协定基于 TCP,能够基于 UDP 协定吗?
MQTT 协定的设计个性中蕴含了一项“高可靠性交付”,它须要一个保障牢靠的底层传输层协定,因而 TCP 协定、TLS 协定、WebSocket 协定都可能作为 MQTT 的底层协定。而无连贯的 UDP 协定会失落或重排数据,不能满足 MQTT 协定的传输须要。
2. MQTT 协定音讯格局
2.1 MQTT 协定音讯的特点
- 1、基于二进制: MQTT 是一种基于二进制的协定,所谓基于二进制, 是指 MQTT 协定操作的元素是二进制数据而不是文本数据;
- 2、命令 & 命令确认格局: MQTT 音讯采纳命令 & 命令确认的格局,每个命令音讯都有一个关联的命令确认音讯,两个音讯之间会通过一个”包惟一标识“字段进行关联???TODO。这与 TCP 的报文确认应答机制是相似的,不过两者的颗粒度是不同的,MQTT 是对整个应用层音讯的确认,而 TCP 是对传输层报文段的确认,或者说是对序列号的确认;
- 3、音讯头很小: MQTT 音讯头最小只须要 2 字节。
2.2 MQTT 协定音讯根本构造
一个 MQTT 音讯由三局部组成:
MQTT 音讯构造 | 形容 | 长度 |
---|---|---|
固定报头(Fixed header) | 存在于所有 MQTT 音讯中 | 2 到 5 字节 |
可变报头(Variable header) | 存在于局部 MQTT 音讯中 | 0 或 N 字节 |
载荷(Payloads) | 存在于局部 MQTT 音讯中 | 0 或 N 字节 |
1、固定报头
所有 MQTT 音讯都蕴含一个固定报头,固定报头由音讯类型、标记位和残余长度三个局部。固定报头长度为 2 ~ 5 字节,具体取决于“残余长度(Remaining Length)”的大小,残余长度示意以后音讯残余局部的字节数,包含可变报头和有效载荷的长度,但不包含残余长度字段自身的字节数。
提醒: 如何判断残余长度的字节数,采纳的是前缀无歧义的表示法。
固定报头格局如下:
MQTT 音讯类型(MQTT Control Packet type)汇总如下:
音讯类型 | 值 | 音讯流转方向 | 形容 | 须要有效载荷 |
---|---|---|---|---|
Reserved | 0 | 禁止 | 保留 | / |
CONNECT | 1 | => | 客户端申请连贯服务器 | ✔ |
CONNACK | 2 | <= | CONNECT 音讯确认 | ✖ |
PUBLISH | 3 | <==> | 客户端公布音讯 | 可选 |
PUBACK | 4 | <==> | PUBLISH 音讯确认(QoS 1) | ✖ |
PUBREC | 5 | <==> | 公布收到(保障交付第一步) | ✖ |
PUBREL | 6 | <==> | 公布开释(保障交付第二步) | ✖ |
PUBCOMP | 7 | <==> | 公布实现(保障交付第三步) | ✖ |
SUBSCRIBE | 8 | => | 客户端订阅音讯 | ✔ |
SUBACK | 9 | <= | SUBSCRIBE 音讯确认 | ✔ |
UNSUBSCRIBE | 10 | => | 客户端勾销订阅 | ✔ |
UNSUBACK | 11 | <= | UNSUBSCRIBE 音讯确认 | ✖ |
PINGREQ | 12 | => | 心跳申请 | ✖ |
PINGRESP | 13 | <= | PINGREQ 音讯确认 | ✖ |
DISCONNECT | 14 | => | 客户端断开连接 | ✖ |
Reserved | 15 | 禁止 | 保留 | / |
2、可变报头
不同音讯的可变报头内容不一样,不过其中有一个比拟通用的字段:
- 包惟一标识(Packet Identifier): SUBSCRIBE,UNSUBSCRIBE,PUBLISH(QoS > 0)的音讯中会蕴含一个 2 字节的惟一标识字段,每次 client 发送这些音讯时,必须调配一个未应用过的惟一标识。而这些音讯的应答音讯,如 PUBACK、PUBREC、PUBREL、UNSUBACK 必须与对应音讯携带雷同的惟一标识。
3、载荷
某些 MQTT 音讯会蕴含一个有效载荷,对于 PUBLISH 音讯来说,有效载荷就是利用音讯。
3. MQTT 协定音讯类型详解
上一节,咱们提到在 MQTT 固定报文头部中会标记 MQTT 音讯类型(MQTT Control Packet type),这一节咱们具体探讨下这些音讯类型。
3.1 连贯音讯
MQTT 的连贯总是产生在 client 和 broker 之间,两个 client 之间不会相互感知。申请连贯时,client 会向 broker 发送 CONNECT
连贯音讯,broker 承受连贯后会响应 CONNACK
连贯确认音讯。一旦连贯建设,连贯会始终放弃关上状态,直到 client 发送 DISCONNECT
断开连接音讯或连贯异常中断。
CONNECT 申请连贯:
CONNECT
是 client 发送给 broker 的首个音讯,并且在一次连贯中,client 只能发送一次 CONNECT
音讯,发送的第二个 CONNECT
音讯会被 broker 当作违反协定解决,并断开连接。在 CONNECT
音讯中,次要蕴含以下内容:
- ClientId 客户端名称: 所有 client 都须要一个名称,broker 会依据 client 名称来跟踪会话,因而 client 名称必须是 惟一的 。如果连贯到 broker 时曾经有一个重名的 clientId,那么会先断开现有 client 的连贯,这将可能导致断开和连贯的死循环,因为大多数 MQTT client 有断线重连机制;
- CleanSession 长久会话: 当 client 连贯到 broker 时,能够应用长久连贯或非长久连贯,
CleanSession
标记决定是否应用长久连贯(当CleanSession = 0
时示意长久连贯),对于长久会话,broker 会存储会话状态;而对于非长久会话,broker 不会存储 client 的任何内容, 具体见第 4.2 节 · 会话状态; - UserName & Password 用户名 & 明码: 用于 broker 认证和受权;
- KeepAlive 保活探测距离: KeepAlive 是以秒单位的工夫距离,指 client 发送两次音讯的最大工夫距离,当 client 和 borker 之间在一段时间内没有数据交互时,client 会发送 PINGREQ 探测音讯 用于判断连贯是否失常,来决定是否要敞开该连贯。KeepAlive 是 MQTT 协定的保活机制,从作用上看与 TCP 的 Keepalive 保活机制是十分相似的,不过 MQTT 协定的保活机制是应用层 client 实现的,而 TCP 的保活机制是“内核”实现的。
- Last Will Message 遗嘱音讯: 遗嘱音讯用于告诉意外停机的 client,每个 client 在连贯时能够设置一个遗嘱音讯,这个遗嘱音讯会存储在 broker 上。当 client 因 “非正常起因” 断开连接时,broker 会将遗嘱音讯分发给订阅了
“Will”
主题的 client。另外,这条遗嘱音讯还能够设置是否为保留音讯(Will Retain
标记)以及服务质量等级(Will Qos
)。
CONNACK 连贯确认:
CONNACK
音讯用于确认 CONNECT
音讯。CONNECT
是 client 发送给 broker 的首个音讯,相应地,broker 发送给 client 的首个音讯肯定是 CONNACK
音讯。在 CONNACK
音讯中,次要蕴含以下内容:
- SessionPresent 长久会话:
SessionPresent
标记示意以后 broker 是否持有与 client 的长久会话。当 broker 接管了一个非长久会话连贯(CleanSession = 1
),SessionPresent 的值始终为 0;而当 broker 接管了一个长久会话连贯(CleanSession = 0
),则 SessionPresent 的值取决于 broker 是否存储了 ClientId 的会话状态; - ReturnCode 响应码: 用于示意连贯申请是否胜利,如果响应码不为 0,则示意连贯失败。
具体取值如下表:
返回码 | 形容 |
---|---|
0 | 连贯已承受 |
1 | 连贯被回绝,不可承受的协定版本 |
2 | 连贯被回绝,标识符被回绝 |
3 | 连贯被回绝,服务器不可用 |
4 | 连贯被回绝,用户名或明码谬误 |
5 | 连贯被回绝,未受权 |
DISCONNECT 断开连接:
DISCONNECT
音讯由 client 发送给 broker,用于断开连接。DISCONNECT 音讯没有可变报头和有效载荷,也没有对应的确认应答音讯,示意一个干净利索地断开连接操作 。断开连接后,client 不能再发送除 CONNECT
音讯之外的音讯,broker 也须要抛弃和以后会话的遗嘱音讯。
3.2 订阅音讯
MQTT 是基于公布订阅模型的协定,在建设连贯后,client 能够向 broker 订阅感兴趣的一个或多个话题。
3.2.1 SUBSCRIBE 订阅
SUBSCRIBE
音讯由 client 发送给 broker,用于订阅感兴趣的话题,SUBSCRIBE
音讯次要蕴含以下内容:
- 主题过滤器列表:
SUBSCRIBE
音讯的有效载荷中至多须要蕴含一个话题过滤器,每个过滤器由一个 Topic 和 QoS 组成,其中的 QoS 指定了指定 client 承受的最大 OoS 等级。
3.2.2 SUBACK 订阅确认
SUBACK
音讯用于确认 SUBSCRIBE
音讯。SUBACK
音讯次要蕴含以下内容:
- 返回码列表: 每个返回码都与 SUBSCRIBE 音讯中的话题过滤器一一对应。
具体取值如下表:
返回码 | 形容 |
---|---|
0x00 | 订阅胜利,最大 QoS 为 0 |
0x01 | 订阅胜利,最大 QoS 为 1 |
0x02 | 订阅胜利,最大 QoS 为 2 |
0x80 | 订阅失败 |
3.2.3 UNSUBSCRIBE 退订
UNSUBSCRIBE
音讯由 client 发送给 broker,用于退订不感兴趣的话题,UNSUBSCRIBE
音讯次要蕴含以下内容:
- 话题列表: UNSUBSCRIBE 音讯的有效载荷中至多须要蕴含一个话题。
3.2.4 UNSUBACK 退订确认
UNSUBACK
音讯用于确认 UNSUBSCRIBE
音讯。UNSUBACK
音讯非常简单,只有一个包惟一标识(位于可变报头)。
3.3 公布音讯
当 MQTT client 在连贯到 broker 之后就能够发送音讯了,每条 PUBLISH
音讯都蕴含一个 topic,broker 会依据 topic 将音讯发送给感兴趣的 client。除此之外,每条音讯还会蕴含一个 Payload,Payload 是真正公布的利用音讯,载荷的内容和格局由应用层决定,MQTT 协定层不关怀。
3.3.1 PUBLISH 公布
PUBLISH
音讯能够由 client 发送给 broker,也能够由 broker 发送给 client,用来运送应用层音讯。PUBLISH 音讯次要蕴含以下内容:
-
QoS 公布服务质量标记: 标记以后
PUBLISH
音讯传送的交付保障程度,分为三个等级, 具体见第 4.3 节 · 公布服务质量 :- QoS 0(默认): 最多发一次
- QoS 1: 起码发一次
- QoS 2: 正好发一次
- RETAIN 保留音讯标记: 标记以后
PUBLISH
音讯是否为保留音讯,当 client 发送给 broker 的 PUBLISH 音讯标记 RETAIN = 1 时,broker 会存储该音讯,当新的 client 注册订阅时,并且匹配该音讯主题时,该保留音讯会发送给订阅者, 具体见第 4.4 节 · 保留音讯; - DUP 重传标记: 标记以后的
PUBLISH
/PUBREL
音讯是否为反复发送音讯。MQTT 协定规定了两种音讯重传的场景,具体见第 4.5 节 · 音讯重传; - TopicName 话题名: 示意载荷数据的公布通道;
- 包惟一标识: 只有 QoS1 和 OoS2 的
PUBLISH
音讯中存在; - 载荷(利用音讯):
PUBLISH
音讯的载荷是真正公布的利用音讯,载荷的内容和格局由应用层决定,MQTT 协定层不关怀。另外,载荷的数据长度等于:固定报头中的残余长度(Remaining Lenght)- 可变报头的长度,载荷长度也能够为零。
3.3.2 公布确认
PUBLISH 音讯的接管方须要发送确认应答,不同 QoS 等级的 PUBLISH 音讯响应的音讯不同:
公布服务质量等级 QoS | 冀望的确认应答 |
---|---|
QoS 0 | 无确认应答 |
OoS 1 | PUBACK 音讯 |
OoS 2 | PUBREC 音讯 PUBREL 音讯 PUBCOMP 音讯 |
3.4 Ping 心跳探测
当 client 和 broker 在一段时间内没有数据交互时,client 会发送 PINGREQ
探测音讯,用于判断连贯是否失常,来决定是否要敞开该连贯,这就是 MQTT 协定的保活机制。
3.4.1 PINGREQ 探测音讯
PINGREQ 音讯由 client 发送给 broker。
3.4.2 PINGRESP 探测确认
PINGRESP 音讯由 broker 发送给 client,代表 client 是存活的。
4. MQTT 协定外围个性
4.1 主题和主题过滤器
MQTT 主题实质上是一种 “寻址模式”,用于将应用层音讯散发到冀望的客户端。MQTT 主题是一种相似于文件系统的分层构造,应用 “/”正斜杠 作为分隔符。
4.1.1 主题格局标准
- 1、辨别大小写;
- 2、采纳 UTF-8 编码的字符串;
- 3、非空字符串,至多蕴含一个字符才无效;
- 4、能够蕴含空;
- 5、一个主题减少“/”前缀或后缀后是不同主题。
4.1.2 主题通配符
客户端订阅主题时,能够订阅确定的主题(例如“group/group123”),也能够应用 “通配符” 来同时订阅多个主题。须要留神的是: 在公布音讯时不容许应用主题通配符,client 每次公布音讯只能公布到单个主题。
- 单级通配符:
+
是单级通配符,单级通配符能够用于任何一个主题级别,但只能匹配一个级别。例如:
主题 | 匹配主题举例 |
---|---|
group/+/123 | group/vip/123 group/temp/123 |
- 多级通配符:
#
是多级通配符,多级通配符能够匹配多个间断级别。须要留神,多级通配符只能用于主题的最初一个级别。例如:
主题 | 匹配主题举例 |
---|---|
group/# | group group/123 group/vip/123 group/temp/123 |
4.1.3 $SYS 主题
$SYS
主题是 broker 上默认创立的只读主题,除此之外,broker 不会默认创立任何主题,所有主题都是由客户端订阅或公布才创立的,都不是永久性的。对于 $SYS
主题的更多介绍在 这里
4.1.4 主题的生存周期
- 创立主题:某个客户端订阅该主题,或者某个客户端向主题公布音讯,同时设置为保留音讯;
- 删除主题:订阅该主题的最初一个客户端断开连接,同时连贯为非长久会话(CleanSession = 1)。
4.2 会话状态
当 client 连贯到 broker 时,能够应用长久连贯或非长久连贯,这是通过 CONNECT
音讯中的 CleanSession 标记来决定的(当 CleanSession = 0
时示意长久连贯)。对于长久会话,broker 会存储会话状态;而对于非长久会话,broker 不会存储 client 的任何内容。会话状态次要蕴含以下内容:
4.2.1 客户端存储的会话状态
- 曾经发送 broker 但没有收到确认的 QoS 1 和 QoS 2
PUBLISH
音讯; - 从 broker 接管但还没有收到确认的 QoS 2
PUBLISH
音讯。
4.2.2 服务端存储的会话状态
- 客户端的订阅;
- 曾经发送到 client 的但没有失去确认的 QoS 1 和 QoS 2
PUBLISH
音讯; - 从客户端接管但还没有确认的 QoS 2
PUBLISH
音讯; - 期待发送到 client 的 QoS 1 和 QoS 2
PUBLISH
音讯; - (可选项)期待发送到客户端的 QoS 0
PUBLISH
音讯。
提醒: 保留音讯不属于会话状态,在会话完结时不会被删除,broker 应该始终存储保留音讯直到被 client 删除。
4.3 QoS 公布服务质量等级
- QoS 0(默认): 最多发一次(不保障音讯交付)
- QoS 1: 起码发一次(保障音讯交付,但可能呈现反复)
- QoS 2: 正好发一次(保障没有反复的音讯交付)
QoS 0 等级的 PUBLISH
音讯的交付能力齐全依赖于底层传输层,QoS 1 和 QoS 2 等级开始在应用层进步 PUBLISH
音讯的交付能力。当音讯失落时,发送端会从新发送早前尝试发送过的 PUBLISH
音讯(DUP = 1),接收者收到音讯也会发送确认响应音讯。
4.3.1 QoS 0 · 最多发一次
在 QoS 0 的等级的 PUBLISH
音讯中不蕴含包惟一标识。发送者不思考音讯交付后果,接收者也不发送响应。接收者最多只能收到一次音讯,也有可能一次也收不到。
4.3.2 OoS 1 · 起码发一次
在 QoS 1 等级的 PUBLISH
音讯中蕴含包惟一标识,发送方会始终将该音讯当作“未确认”的音讯,直到收到对应的 PUBACK
确认音讯。具体音讯流如下:
提醒: 理论的消息传递是在 client 和 broker 之间进行的,这 4 个步骤是简化为发送方和接管方之间的消息传递。
- 1、发送方存储利用音讯;
- 2、发送方发送
PUBLISH
(QoS = 1, DUP = 0, <PID>)音讯; - 3、接管方收到
PUBLISH
音讯,并响应PUBACK
(<PID>)确认音讯; - 4、发送方收到
PUBACK
音讯,并删除存储的利用音讯。
4.3.3 QoS2 · 正好发一次
QoS 2 是最高的服务质量,保障音讯不会失落也不会反复,毛病是会减少开销。在 QoS 2 等级的 PUBLISH
音讯中蕴含包惟一标识,发送者会始终将该音讯当作“未确认”的音讯,晓得收到对应的 PUBCOMP
确认音讯。
- 1、发送方存储音讯;
- 2、发送方发送
PUBLISH
(QoS = 2, DUP = 0, <PID>)音讯; - 3、接管方收到
PUBLISH
音讯,并存储音讯; - 4、接管方响应
PUBREC
(<PID>)音讯; - 5、发送方收到
PUBREC
音讯,并发送PUBREL
(<PID>)音讯; - 6、接管方向下层利用告诉音讯;
- 7、接管方响应
PUBCOMP
(<PID>)音讯; - 8、发送方收到
PUBCOMP
音讯,并删除存储的利用音讯。
4.4 RETAIN 保留音讯
当 client 公布某个主题的音讯时,broker 会将该音讯分发给任何已订阅该主题的 client,随后这条音讯会从 broker 上删除。能够设置 RETAIN
保留标记设置该 PUBLISH 音讯为保留音讯,broker 会存储该主题的最初一条保留音讯,当新的 client 注册订阅时,并且匹配该音讯主题时,该保留音讯会发送给订阅者。 须要留神:broker 只会为每个主题保留最近一条保留音讯,新收到的 RETAIN = 1 的音讯会笼罩本来那条保留音讯;
长久会话 & 服务质量等级 & 保留音讯都会影响新订阅者是否承受音讯,总结如下表:
- 对于保留音讯(Retain Flag 为 Ture),新订阅者总能收到最初一条保留音讯(图中绿色局部);
- 对于长久会话(Clean Session Flag 为 Flase)且订阅者订阅 OoS 大于等于 1,总能收到所有 OoS 大于等于 1 的音讯(图中黄色局部)。
4.5 音讯重传
标记 DUP = 1
的音讯是被反复发送的音讯,MQTT 音讯重传有 2 种场景:
- 1、PUBLISH / PUBREL 音讯发送后,在规定工夫内没有收到确认应答音讯,则重传这个音讯;
- 2、在应用长久会话时,client 从新连贯后,broker 会主动重传未确认的音讯。
须要留神:DUP 标记只对 OoS > 0 的音讯无效,所有 QoS = 0 的音讯 DUP 标记必须设置为 0;
TCP 协定有报文重传机制,为什么 MQTT 协定还有音讯重传机制?
TCP 协定的报文重传机制是对所有 TCP 报文无效的重传机制,而 MQTT 协定的音讯重传机制只对一小部分音讯无效,用于实现更牢靠的音讯交付保障。尽管 TCP 协定在个别状况下能够保障不丢包,然而这并不是相对的,仍然存在申请超时或者连贯中断等状况。而 MQTT 协定的 QoS 1 和 QoS 2 要求更牢靠的交付能力,并且须要在客户端重连后也能保障交付。因而,MQTT 协定也定义了一个音讯重传机制。
5. 总结
到这里,对于 MQTT 协定的工作原理 & 协定音讯格局 & 外围个性等内容就介绍完了。我晓得你应该会对 MQTT 协定的实战利用更加感兴趣,下一篇文章里,我将带你实现基于 MQTT 协定的 IM 服务,请关注。
参考资料
- MQTT 官网
- MQTT 协定中文版
- MQTT Protocol Guide —— Steve 著
- MQTT 协定是个啥?这篇文章通知你!—— cxuan 著
- Android 音讯推送 MQTT 实战 —— wildma 著
- Battle of The Protocols (HTTP vs. Websockets vs. MQTT) —— Ronak Singh 著
我是小彭,带你构建 Android 常识体系。技术和职场问题,请关注公众号 [彭旭锐] 私信我发问。