说到做到!(三)

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

消息类型

发布

当 MQTT client 在连接到 broker 之后就可以发送消息了,MQTT 使用的是基于 topic 主题的过滤。每条消息都应该包含一个 topic ,broker 可以使用 topic 将消息发送给感兴趣的 client。除此之外,每条消息还会包含一个负载(Payload),Payload 中包含要以字节形式发送的数据。

MQTT 是数据无关性的,也就是说数据是由发布者 - publisher 决定要发送的是 XML 、JSON 还是二进制数据、文本数据。

MQTT 中的 PUBLISH 消息结构如下。

微信图片_20220416181913.png

  • Packet Identifier:这个 PacketId 标识在 client 和 broker 之间唯一的消息标识。packetId 仅与大于零的 Qos 级别相关。
  • TopicName:主题名称是一个简单的字符串,/ 代表着分层结构。
  • Qos:这个数字表示的是服务质量水平,服务质量水平有三个等级:0、1 和 2,服务级别决定了消息到达 client 或者 broker 的保证类型,来决定消息是否丢失。
  • RetainFlag:这个标志表示 broker 将最近收到的一条 RETAIN 标志位为true的消息保存在服务器端(内存或者文件)。

MQTT 服务器只会为每一个 Topic 保存最近收到的一条 RETAIN 标志位为true的消息。也就是说,如果MQTT 服务器上已经为某个 Topic 保存了一条 Retained 消息,当客户端再次发布一条新的 Retained 消息时,那么服务器上原来的那条消息会被覆盖。

  • Payload:这个是每条消息的实际内容。MQTT 是数据无关性的。可以发送任何文本、图像、加密数据以及二进制数据。
  • Dupflag:这个标志表示该消息是重复的并且由于预期的 client 或者 broker 没有确认所以重新发送了一次。这个标志仅仅与 Qos 大于 0 相关。

当 client 向 broker 发送消息时,broker 会读取消息,根据 Qos 的级别进行消息确认,然后处理消息。处理消息其实就是确定哪些 subscriber 订阅了 topic 并将消息发送给他们。

微信图片_20220416181921.png

最初发布消息的 client 只关心将 PUBLISH 消息发送给 broker,一旦 broker 收到 PUBLISH 消息,broker 就有责任将其传递给所有 subscriber。发布消息的 client 不会知道是否有人对发布的消息感兴趣,同时也不知道多少 client 从 broker 收到了消息。

订阅

client 会向 broker 发送 SUBSCRIBE 消息来接收有关感兴趣的 topic,这个 SUBSCRIBE 消息非常简单,它包含了一个唯一的数据包标识和一个订阅列表。

微信图片_20220416181924.png

  • Packet Identifier:这个 PacketId 和上面的 PacketId 一样,都表示消息的唯一标识符。
  • ListOfSubscriptions:SUBSCRIBE 消息可以包含一个 client 的多个订阅,每个订阅都会由一个 topic 和一个 Qos 构成。订阅消息中的 topic 可以包含通配符。

确认消息

client 在向 broker 发送 SUBSCRIBE 消息后,为了确认每个订阅,broker 会向 client 发送 SUBACK 确认消息。这个 SUBACK 包含原始 SUBSCRIBE 消息的 packetId 和返回码列表。

微信图片_20220416181928.png

其中

  • Packet Identifier :这个数据包标识符和 SUBSCRIBE 中的相同。
  • ReturnCode:broker 为每个接收到的 SUBSCRIBE 消息的 topic/Qos 对发送一个返回码。例如,如果 SUBSCRIBE 消息有五个订阅消息,则 SUBACK 消息包含五个返回码作为响应。

到现在我们已经探讨过了三种消息类型,发布 - 订阅 - 确认消息,这三种消息的示意图如下。

微信图片_20220416181931.png

退订

SUBSCRIBE 消息对应的是 UNSUBSCRIBE 消息,这条消息发送后,broker 会删除关于 client 的订阅。所以,UNSUBSCRIBE 消息与 SUBSCRIBE 消息类似,都具有 packetId 和 topic 列表。

微信图片_20220416181934.png

确认退订

取消订阅也需要 broker 的确认,此时 broker 会向 client 发送一个 UNSUBACK 消息,这个 UNSUBACK 消息非常简单,只有一个 packetId 数据标识符。

微信图片_20220416181937.png

退订和确认退订的流程如下。

微信图片_20220416181941.png

当 client 收到来自 broker 的 UNSUBACK 消息后,就可以认为 UNSUBSCRIBE 消息中的订阅被删除了。

聊聊 Topic

聊了这么多关于 MQTT 的内容,但是我们还没有好好聊过 Topic。在 MQTT 中,Topic 是指 broker 为每个连接的 client 过滤消息的 UTF-8 字符串。Topic 是一种分层的结构,可以由一个或者多个 Topic 组成。每个 Topic 由 / 进行分割。

微信图片_20220416181945.png

与传统的消息队列相比,MQTT Topic 非常轻量级,client 在发布或订阅之前不需要先创建所需要的 Topic,broker 在接收每个 Topic 前不用进行初始化操作。

通配符

当客户端订阅 Topic 时,它可以订阅已发布消息的确切 Topic,也可以使用通配符来同时订阅多个 Topic。通配符有两种:单级和多级

单级通配符

单级通配符可以替换 Topic 的一个级别,+ 号代表 Topic 中的单级通配符。

微信图片_20220416181949.png

如果 Topic 包含任意字符串而不是通配符,则任何 Topic 都能够和单级通配符匹配。例如

myhome/groundfloor/+/temperature 就有下面这几种匹配方式。

微信图片_20220416181953.png

多级通配符

多级通配符涵盖多个 Topic,# 代表 Topic 中的多级通配符。为了让 broker 能够确定和哪些 Topic 匹配,多级通配符必须作为 Topic 中的最后一个字符放置,并以 / 开头。

微信图片_20220416181957.png

下面是 myhome/groundfloor/# 的几个例子

微信图片_20220416182000.png

当 client 订阅带有多级通配符的 Topic 时,不论 Topic 有多长多深,它都会收到通配符之前 Topic 的所有消息。如果你只将 Topic 定义为 # 的话,那么你将会收到所有的消息。

总结

这篇文章的起因是有小伙伴留言说想要了解一下 MQTT 协议,因为之前没有了解过这个协议,更别谈写了。MQTT 相当于是舒适区之外的新东西,是值得花时间研究的,这也是我写这篇文章的原因。

文中可能有写的不太好或者有勘误的地方,大家多多提出建设性意见呀~ 我们下篇文章见。

相关实践学习
消息队列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
相关文章
|
12月前
|
Web App开发 开发者
利用chrome控制台调试post请求
利用chrome控制台调试post请求
232 0
|
5月前
|
SQL XML Java
ruoyi若依框架@DataScope注解使用以及碰到的一些问题
ruoyi若依框架@DataScope注解使用以及碰到的一些问题
935 0
|
XML 存储 人工智能
分享:包括 AI 绘画在内的超齐全免费可用的API 大全
我给大家整理了超级齐全的免费可用 API,包括 AI 绘画在内,有需要的小伙伴赶紧收藏了。
1207 0
分享:包括 AI 绘画在内的超齐全免费可用的API 大全
|
JavaScript UED
vue利用双向数据绑定实现多个输入框回显并且加入条件
vue利用双向数据绑定实现多个输入框回显并且加入条件
156 0
|
存储 XML 缓存
Activiti原理分析(一)从一个简单流程开始
本系列文章将基于 Activiti 6 源代码对 Activiti 的原理进行深入剖析,让读者快速知其然,同时知其所以然。 第一篇文章将分析一个简单流程在 Activiti 中的执行流程,借此把 Activiti 底层的一些概念快速梳理一遍,让读者对 Activiti 的底层实现有个大概了解,知晓每张表的作用。内容都是笔者从源码里分析出来或者核对过的,比一般的文档更加翔实靠谱。
3494 2
Activiti原理分析(一)从一个简单流程开始
|
开发工具 Android开发 开发者
鸿蒙、OpenHarmony、HarmonyOS傻傻的分不清楚。。。看这篇就够了
很多人对鸿蒙、OpenHarmony、HarmonyOS这些术语傻傻的分不清楚,那么本文就做一些解答。 6月4日,华为发布了《关于规范HarmonyOS沟通口径的通知》(以下简称《通知》),原文在网上都能搜到,这里就不贴了。本人对该通知做一些解读如下。
1099 0
|
Prometheus Kubernetes 监控
通过Kubernetes监控探索应用架构,发现预期外的流量
Kubernetes 监控立足于应用监控之下的 Kubernetes 容器界面和底层操作系统,是 Kubernetes 集群软件栈端到端可观测性的一体化解决方案,在 Kubernetes 监控中可以同时看到关联的所有层的观测数据。我们希望通过 Kubernetes 监控的一系列最佳实践,让大家能够使用 Kubernetes 监控解决 Kubernetes 环境下棘手的可观测问题。
通过Kubernetes监控探索应用架构,发现预期外的流量
|
物联网 开发工具 开发者
如何适配ESL应用平台到新的硬件板
本文介绍 如何适配ESL应用平台到新的硬件板
453 0
如何适配ESL应用平台到新的硬件板
|
分布式计算 分布式数据库 数据库
Spark on HBase Connector:如何在Spark侧设置HBase参数
前言 X-Pack Spark可以使用Spark on HBase Connector直接对接HBase数据库,读取HBase数据表数据。有时在读取HBase时需要设置HBase的一些参数调整性能,例如通过设置hbase.client.scanner.caching的大小调整读取HBase数据的性能。
2169 0