说到做到!(二)

简介: MQTT 协议的全称是 Message Queuing Telemetry Transport,翻译为消息队列传输探测,它是 ISO 标准下的一种基于发布 - 订阅模式的消息协议,它是基于 TCP/IP 协议簇的,它是为了改善网络设备硬件的性能和网络的性能来设计的。MQTT 一般多用于 IoT 即物联网上,广泛应用于工业级别的应用场景,比如汽车、制造、石油、天然气等。

MQTT broker

与 MQTT client 对应的就是 MQTT broker,broker 是任何发布/订阅机构的核心,根据实现的不同,代理可以处理多达数百万连接的 MQTT client。

broker 负责接收所有消息,过滤消息,确定是哪个 client 订阅了每条消息,并将消息发送给对应的 client,broker 还负责保存会话数据,这些数据包括订阅的和错过的消息。broker 还负责客户端的身份验证和授权。

MQTT Connection

MQTT 是基于 TCP/IP 协议基础之上的,所以 MQTT 的 client 和 broker 都需要 TCP/IP 协议的支持。

微信图片_20220416181726.png

MQTT 的连接总是在 client 和 broker 之间进行,client 和 client 之间并不会相互连接。如果要发起连接的话,那么 client 就会向 broker 发起 CONNECT 消息,代理会使用 CONNACK 消息和状态码进行响应。一旦 client 和 broker 的连接建立后,broker 就会使客户端的连接一直处于打开状态,直到 client 发出断开命令或者连接中断。

微信图片_20220416181730.png

消息报文

MQTT 的消息报文主要分为 CONNECT 和 CONNACK 消息。

CONNECT

我们上面提到了为了初始化连接,需要 client 向 broker 发送 CONNECT 消息,如果这个 CONNECT 消息格式错误或者打开套接字(因为基于 TCP/IP 协议栈需要初始化 Socket 连接)时间过长,亦或是发送连接消息时间过长的话,broker 就会关闭这条连接。

一个 MQTT 客户端发送一条 CONNECT 连接,这条 CONNECT 连接可能会包含下面这些信息:

微信图片_20220416181734.png

我这里解释一下这些信息都是什么概念

  • ClientId:显而易见,这个就是每个客户端的 ID 标识,也就是连接到 MQTT broker 的每个 client。这个 ID 应该是每个 client 和 broker 唯一的,如果你不需要 broker 持有状态的话,你可以发送一个空的 ClientId,空的 ClientId 会没有任何状态。在这种情况下,ClientSession 需要设置为 true,否则将会拒绝连接。

clientSession 是什么我们下面会说。

  • CleanSession:CleanSession 会话标志会告诉 broker client 是否需要建立持久会话。在持久会话 (CleanSession = false)中,broker 存储 client 的所有订阅以及服务质量(Qos) 是 1 或 2 订阅的 client 的所有丢失的消息。如果会话不是持久的(CleanSession = true),那么 broker 则不会为 client 存储任何内容并且会清除先前持久会话中的所有信息。
  • Username/Password :MQTT 会发送 username 和 password 进行 client 认证和授权。如果此信息没有经过加密或者 hash ,那么密码将会以纯文本的形式发送。所以,一般强烈建议 username 和 password 要经过加密安全传输。像 HiveMQ 这样的 broker 可以与 SSL 证书进行身份验证,因此不需要用户名和密码。
  • LastWillxxx :LastWillxxx 表示的是遗愿,client 在连接 broker 的时候将会设立一个遗愿,这个遗愿会保存在 broker 中,当 client 因为非正常原因断开与 broker 的连接时,broker 会将遗愿发送给订阅了这个 topic(订阅遗愿的 topic)的 client。
  • keepAlive:keepAlive 是 client 在连接建立时与 broker 通信的时间间隔,通常以秒为单位。这个时间指的是 client 与 broker 在不发送消息下所能承受的最大时长。

在聊完 client 与 broker 之间发送建立连接的 CONNECT 消息后,我们再来聊一下 broker 需要对 CONNECT 进行确认的 CONNACK 消息。

CONNACK

当 broker 收到 CONNECT 消息时,它有义务回复 CONNACK 消息进行响应。CONNACK 消息包括两部分内容

微信图片_20220416181739.png

  • SessionPresent:会话当前标识,这个标志会告诉 client 当前 broker 是否有一个持久性会话与 client 进行交互。SessionPresent 标志和 CleanSession 标志有关,当 client 在 CleanSession 设置为 true 的情况下连接时,SessionPresent 始终为 false,因为没有持久性会话可以使用。如果 CleanSession 设置为 false,则有两种可能性,如果 ClientId 的会话信息可用,并且 broker 已经存储了会话信息,那么 SessionPresent 为 true,否则如果没有 ClientId 的任何会话信息,那么 SessionPresent 为 false。

微信图片_20220416181744.png



  • ReturnCode:CONNACK 消息中的第二个标志是连接确认标志。这个标志包含一个返回码,告诉客户端连接尝试是否成功。连接确认标志有下面这些选项。
返回码 返回码含义
0 已接受连接
1 连接被拒绝,不可接受的协议版本
2 连接被拒绝,标识符被拒绝
3 连接被拒绝,服务器不可用
4 连接被拒绝,用户名或密码错误
5 连接被拒绝,未授权
相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
6月前
|
Serverless
基于Logistic函数的负荷需求响应(matlab代码)
基于Logistic函数的负荷需求响应(matlab代码)
|
6月前
|
SQL 关系型数据库 MySQL
关系型数据库使用 DELETE 语句删除
`DELETE` SQL 语句用于从关系型数据库表中删除记录。可删除所有记录(如 `DELETE FROM students;`)或依据条件(如 `DELETE FROM students WHERE age > 25;`)。某些数据库支持使用 `OUTPUT` 或 `RETURNING` 子句返回被删除记录。还能通过子查询(如基于 `failed_exams` 删除 `students` 表记录)及触发器配合执行。注意,`DELETE` 在事务中执行,需谨慎操作并确保数据备份。
101 1
|
C#
WPF BitmapImage 占用资源无法释放、无法删除问题
原文:WPF BitmapImage 占用资源无法释放、无法删除问题 使用Image控件显示图片后,虽然自己释放了图片资源,Image.Source =null 了一下,但是图片实际没有释放。解决方案:修改加载方式~        public static BitmapImage GetImage...
2107 1
|
编解码
效率新秀 | 详细解读:如何让EfficientNet更加高效、速度更快(二)
效率新秀 | 详细解读:如何让EfficientNet更加高效、速度更快(二)
82 0
|
机器学习/深度学习 自然语言处理 数据可视化
2016~2022 文字生成图像 Text to image(T2I)论文整理 阅读路线和阅读指南
2016~2022 文字生成图像 Text to image(T2I)论文整理 阅读路线和阅读指南
|
物联网 Linux 弹性计算
阿里云ECS飞天计划使用感受
对阿里云的云服务器一个月的使用感受,对服务器的基本了解,例如服务器的基本配置,对自己的帮助,通过服务器的的使用学习到更多的知识。
阿里云ECS飞天计划使用感受
|
弹性计算
关于使用阿里云ECS的体验
关于使用阿里云ECS云服务器的个人体验以及一些平时使用时遇到的问题和解决办法。
|
算法 JavaScript
快来看JS的的几个常用算法(持续更新中)
快来看JS的的几个常用算法(持续更新中)
|
关系型数据库 PostgreSQL Oracle
|
Web App开发 Java Docker