最新发布《数智时代的AI人才粮仓模型解读白皮书(2024版)》,立即领取! 了解详情
写点什么

MQTT 协议之连接

  • 2019-11-20
  • 本文字数:3292 字

    阅读完需:约 11 分钟

MQTT协议之连接

在之前的文章中已简单介绍了 MQTT 协议报文的格式,本篇文章将对集中的连接协议进行详细的介绍,以及自己对该协议的一些思考和理解。

1 CONNECT

客户端和服务端建立连接之后,发送的第一个报文必须是 CONNECT。客户端只能发送一次 CONNECT 报文,如果服务端收到了第二个 CONNECT 报文,必须将其视为错误,并且断开连接。

协议格式

固定报头

可变报头

可变报头分为四个部分,分别是协议名称(Protocol Name),协议级别(Protocol Level),连接标志(Connect Flags),保持连接(Keep Alive)。

协议名称


  1. 协议名是 MQTT 的 UTF-8 编码的字符串。MQTT 规范的后续版本不会改变这个字符串的偏移和长度。

  2. 如果协议不正确服务端断开连接。(MQTT 3.1.1)其他规范中可以有其他规范。

  3. 数据包检测工具,可以使用协议名来识别 MQTT 流量。

协议级别


  1. 使用 8 位来表示协议的修订版本级别。MQTT3.1.1 的协议级别为 4。这个也是 MQTT5 的由来,MQTT5 的协议级别为 5,故称为 MQTT5。

  2. 服务端收到一个自己不支持的协议级别的时候,必须返回一个 returnCode 为 0x01 的 CONNACK 的报文给客户端,随后服务端断开相应的连接。

  3. 连接标志



  1. 服务端必须校验连接标志中的预留字段是否为 0,如果不为 0,必须断开该连接。

  2. 清理会话标志


A. 清理会话标志的表现


a.清理会话标志为0(false)
i.如果已存在相同ClientId的会话,则必须恢复相应的会话。
ii.不存在相同ClientId的会话,则重新创建一个新的会话。
iii.客户端和服务端断开连接后,服务端必须保存相应的会话信息。
iv.连接断开后,服务端必须保留该Session所有的订阅Topic的Qos1和Qos2的消息。服务端也可以保留Qos0的消息,此为可选项。
b.清理会话标志1(true) 客户端和服务端都必须丢弃之前的会话并且重新创建一个会话。会话信息是和连接绑定的,该会话相关的数据,不能被后续的会话使用
复制代码


B. 状态信息


a. 客户端
i.Qos和Qos2已经发送到服务端,但是还没有完全结束的消息。
ii.Qos2已经收到的消息,但是还没有最终完成的消息。
b. 服务端
i.会话存在的信息,即时会话的其他内容都是空的。
ii.客户端的订阅信息。
iii.Qos1和Qos2已经发送到客户端但是没有完全结束的消息。
iv.Qos2已经收到的,但是还没有最终结束的消息。
v.等待发送给客户端的Qos1和Qos2消息。
vi.可选的等待发送给客户端的Qos0的消息。
复制代码


C. 注意事项


a. 保留消息不是服务端会话状态的一部分,会话中止时不能删除。
b. 清理会话设置为1时,客户端和服务端的状态删除不需要是原子操作。
c. 如果希望保证在异常时的状态一致性,可以通过清理会话标志始终设置为1直到成功连接上服务。
复制代码


  1. 遗嘱标志 遗嘱标志设置了(1 或者 true)之后,连接建立成功之后,遗嘱消息会被存储在服务端并且和这个网络连接绑定,当该网络连接异常关闭时,服务端必须发布这个遗嘱消息,除非客户端发送了 DISCONNECT 消息后,服务端删除了该消息。


A. 遗嘱消息发布的条件,包括但不限于


a. 服务端检测到IO错误或者网络故障。
b. 客户端在保持连接的时间内未能通讯。
c. 客户端没有先发送DISCONNECT报文而直接关闭了连接。
d. 由于协议错误服务端关闭了网络连接。
复制代码


B. 注意事项


a. 遗嘱标志设置后,Will Qos和Will Retain会被用到,有效载荷必需包含Will Topic和Will Message。
b. 被发布或收到客户端的DISCONNECT报文之后,遗嘱消息必须从存储中删除。
c. 遗嘱标志设置为0时,Will Qos和Will Retain字段必须设置为0,并且有效载荷中不能包含Will Topic和Will Message.
d. 服务端应该迅速发布遗嘱消息。在关机或者故障的情况下,服务端可以推迟发布消息到服务恢复。
复制代码


  1. 遗嘱消息 Qos 遗嘱消息的 QOS。

  2. 遗嘱预留消息 遗嘱消息的保留标志。

  3. 用户名标志 表示是否又用户名在有效载荷中。

  4. 密码标志 表示是否又密码在有效载荷中,如果用户名标志为 0,该字段也必须为 0。

  5. 保持连接



  1. 保持连接单位为秒(s),两个 Byte 16 位表示,所以最长的 keepAlive 的时间为 18 小时 12 分 15 秒。

  2. 表示的是客户端从发送完一个报文到发送下一个报文,两者之间允许的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值,如果没有其他的报文可以发送,客户端必须发送 PINGREQ 报文。

  3. 客户端可以随时发送 PINGREQ 报文,并且根绝 PINGRESP 的报文判断和服务端的活动状态。

  4. 如果服务端在 1.5 倍的保持连接(非 0)时间内没有收到任何的报文,服务端必须断开相应的连接。

  5. 客户端发送 PINGREQ 之后,在规定的时间没有收到服务端的 PINGRESP 报文的回应,客户端应该断开该连接。

  6. 保持连接设置为 0 表示关闭保持连接的功能。服务端不需要因为客户端的不活跃而断开连接。

  7. 服务端主要认为客户端是不活跃或者无响应的,都可以断开客户端连接。

有效载荷

有效载荷中的字段包含一个或者多个是根据可变报头中的标志来决定有无的。如果存在的话,必须按照如下的顺序,ClientId, Will Topic, Will Message, User Name, Password。


  1. ClientId

  2. A. 每个客户端连接服务端必须有一个唯一的 ClientId 标志。该标志是客户端和服务端用来区分会话的唯一标志。

  3. B. 必须提供并且必须是 CONNECT 报文有效负载的第一个字段。

  4. C. 必须[1-23]的 UTF-8 编码,包含的内容必须是[0-9][a-z][A-Z]。服务端也可以支持更长的以及其他的 UTF-8 字符。

  5. D. 如果 ClientId 是 0 字节的,服务端必须为其赋予一个唯一的标志,然后进行后续的处理。ClientId 为 0 字节时有如下的限制,

  6. a. 清理会话标志必须设置为 1,否则服务端返回 returnCode=0x02 的 CONNACK,并且关闭该网络连接。

  7. E. 服务端如果拒绝该 ClientId,服务端必须返回 returnCode=0x02 的 CONNACK,并且关闭该网络连接。

  8. Will Topic 遗嘱消息的 topic,必须是 UTF-8 编码的字符串。

  9. Will Message 遗嘱消息的内容。

  10. User Name 用户名,必须是 UTF-8 的字符串。

  11. Passowrd



由两个 Byte 表示的二进制数据标识。最长可以为 65535Bytes 的二进制。

响应

检验
复制代码


  1. 网络建立后,服务端在指定时间内没有收到客户端的 CONNECT 消息,服务端应该关闭连接。

  2. 服务端必须按照以上规范来验证 CONNECT 报文,如果不符合规范,服务端必须关闭连接,而且不需要发送 CONNACK。

  3. 服务端可以检查 CONNECT 的内容,如果任何一个检查没有通过,应该返回一个指定的 CONNACK 的报文,并且必须关闭该连接。

  4. 服务端检验通过后的处理

  5. 如果又相同 ClientId 的连接,服务端必须关闭已有的连接。

  6. 服务端需要处理和清理会话相关的内容。

  7. 返回客户端 CONNACK。

  8. 开始消息投递和保活监控。 备注:客户端可以不等待 CONNACK 的返回,直接发送其他的控制报文,如果服务端拒绝了相应的连接,服务端必须不处理 CONNECT 报文之后的任何协议。

  9. CONNACK

  10. 服务端返回给客户端的第一个协议必须是 CONNACK 报文。

  11. 协议格式

  12. 固定报头



固定报头中只有报文类型为2。
可变报头
复制代码



可变报头包含连接确认标志和连接返回码。
连接确认标志
复制代码


  1. 保留位必须为 0

  2. 当前会话 SP

  3. A. 服务端如果没有之前的会话时,该值为 0。

  4. B. 如果 returnCode=0(连接被接收),服务端存在之前的会话,该值为 1。

  5. C. 该标志能够是客户端和服务端是否又已存在会话保持一致,如果两者不一致,客户端可以选择断开连接或者继续连接。客户端可以通过断开连接,清理会话设置为 1,再次连接,然后再次断开连接的方式来丢弃客户端和服务端的会话状态。

  6. D. 如果返回码非 0,会话状态必须为 0。

  7. 连接返回码



 有效载荷
CONNACK报文没有有效载荷字段。
复制代码

2 总结

  1. 连接报文是 MQTT 连接建立之后的第一个报文,如果不是将会断开连接,并且连接报文也只能发送一次。

  2. 清理会话的设置也是通过连接报文进行设置,可以通过重新连接,设置清理会话的标志来保持客户端和服务端的会话信息。

  3. 遗言是跟连接绑定的,在用户非正常 DISCONNECT 的情况下将触发遗言的发布。

  4. 保持连接是检测客户端发送到服务端的消息的间隔时间,协议固定在 1.5 倍的保持连接的时间,会断开连接。现在使用的 EMQ 的保持连接的机制,KeepAlive * backoff = CheckTime,从客户端建立连接开始进行循环检测,连续两次没有检测到 Socket 报文的话,则认为超时,故真实的超时时间为 CheckTime * 2 < RealTimeout < CheckTime * 3。


本文转载自公众号 360 云计算(ID:hulktalk)。


原文链接:


https://mp.weixin.qq.com/s/lq7uN8CUf3m9CmnqLxK01A


2019-11-20 11:371399

评论

发布
暂无评论
发现更多内容

构建数字合作格局 赋能政企行业通信——首届WECC 2021即将召开

融云 RongCloud

音视频 IT, 通信 通信云 会议

太绝了吧! 终于有人能把TCP/IP 协议讲的明明白白了

程序员 架构 面试 后端 java

Apache ShardingSphere 在京东白条场景的落地之旅

SphereEx

开源 数据架构 架构设计 ShardingSphere SphereEx

云栖大会|盛宴之下,共赴一场视频云的进化论

阿里云视频云

阿里云 音视频 WebRTC 视频云 云栖大会

百亿级系统架构首公开!阿里这份300多页的设计实录你还没有吗?

Java 程序员 架构 面试 后端

在Vue中使用JSX,很easy的

华为云开发者联盟

JavaScript Vue Vue3 JSX 渲染函数

Elasticsearch 分片速度、进度及故障排查(qbit)

qbit

elasticsearch shard

写给初学者,一文搞懂大数据学习、岗位、面试及简历

五分钟学大数据

大数据

主数据与主数据管理(数据治理)

KoLee

数据治理 数字化 主数据管理 主数据

涨薪60%,从美团干到阿里p7,这份Github上的面试笔记把所有Java知识都写出来了

Java 程序员 架构 面试 后端

Elasticsearch 快照相关(qbit)

qbit

19. 删除链表的倒数第N个数(链表)

黄敏

元宇宙NFT区块链游戏系统开发

2021Flexera云报告:企业积极拥抱多云,但云上成本仍然居高不下

行云管家

区块链 云计算 企业上云 上云

遭 GitHub 连夜封杀下架?被泄露的阿里内部 Java 面试手册到底有多强?

收到请回复

Java 面试 阿里 大厂Offer

量化模拟线上流量实践

FunTester

性能测试 接口测试 测试框架 FunTester 线上流量

详解物联网Modbus通讯协议

华为云开发者联盟

物联网 通信 Modbus 通讯协议 TCP通信

DataOps(数据运维)指南 - 数据管理的新时代

码语者

DataOps

面试官提问:如何通过sql方式将数据库表行转列?

Java 数据库 sql 面试 后端

分布式缓存技术

黄敏

Python 的 sum():Pythonic 的求和方法

华为云开发者联盟

Python 列表 元组 Pythonic 求和

第 17 章 -《Linux 一学就会》- Linux计划任务与日志的管理

学神来啦

Linux 运维 linux学习 linux云计算 linux基础

Python代码阅读(第37篇):获取两个列表中相同的元素

Felix

Python 编程 Code Programing 阅读代码

211本+985硕+计算机专业投面百度,坐等一周迎来三面,已拿offer

Java 学习 程序员 架构 大厂面试

安全稳定便捷! 融云赋能“轻云会议”满足政府在线会议需求

融云 RongCloud

云计算 音视频 通信 会议 视频云

WhatsApp 如何启用端到端加密备份数据

CatTalk

facebook 安全 端到端加密

解读鸿蒙轻内核的监控器:异常钩子函数

华为云开发者联盟

鸿蒙 钩子函数 任务栈 OpenHarmony 异常钩子函数

Android技术分享| 【自习室】自定义View代替通知动画(1)

anyRTC开发者

android 音视频 WebRTC 在线教育 移动开发

J2PaaS低代码平台的开源,将进一步助力企业数字化

J2PaaS低代码平台

低代码 低代码开发 低代码开发平台

Alibaba最新神作!耗时182天肝出来的1015页分布式全栈手册太香了

编程 程序员 IT 计算机 java

三面阿里,有惊无险成功拿到offer定级P7,只能说是真的难

Java 编程 java架构

MQTT协议之连接_文化 & 方法_张超_InfoQ精选文章