MQTT
1. MQTT是什么
MQTT是一种协议,基于发布/订阅模式的物联网通信协议。
凭借简单易实现、支持QoS、报文小等特点,这些特点使它的适用范围非常广泛。
2. MQTT的基础概念
基础概念 | 协议进阶 | MQTT 5.0 协议新增特性 |
---|---|---|
客户端 (Client) | 消息服务质量(QoS) | 会话过期 |
服务器(Server) | 清除会话(Clean Session) | 为所有响应报文提供原因码 |
会话(Session) | 保活心跳(Keep Alive) | 请求/响应 |
订阅(Subscription) | 保留消息(Retained Message) | 共享订阅 |
主题名(Topic Name) | 遗嘱消息(Will Message) | 主题别名 |
主题过滤器(Topic Filter) | ||
载荷(Payload) |
- 客户端 (Client):使用 MQTT 协议的程序或设备。
- 服务器(Server):在发送消息的客户端与已订阅的客户端之间充当中介角色的程序或设备。
- 会话(Session):每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。
- 订阅(Subscription):订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。
- 主题名(Topic Name):附加在应用消息上的一个标签,被用于匹配服务端已存在的订阅。服务端会向所有匹配订阅的客户端发送此应用消息。
- 主题过滤器(Topic Filter):仅在订阅时使用的主题表达式,可以包含通配符,以匹配多个主题名。
- 载荷(Payload):对于 PUBLISH 报文来说载荷就是业务消息,它可以是任意格式(二进制、十六进制、普通字符串、JSON 字符串、Base64)的数据。消息订阅者所具体接收的内容。
3. 为什么使用MQTT
3.1. 发布订阅模式
发布订阅模式是传统 Client/Server 模式的一种解耦方案。
发布者通过Broker与消费者之间通信,Broker的作用是将收到的消息通过某种过滤规则
,正确地发送给消费者。
发布/订阅模式 相对于 客户端/服务器模式 的好处在于:
- 发布者和消费者之间不必预先知道对方的存在,比如不需要预先沟通对方的 IP Address 和 Port
- 发布者和消费者之间不必同时运行。因为 Broker 是一直运行的。
4. MQTT应用场景
5. MQTT设计原则
必须支持 QoS(设备网络环境复杂)。
必须轻量且省带宽(因为那时候带宽很贵)。
必须数据无关(不关心 Payload 数据格式)。
必须有持续地会话感知能力(时刻知道设备是否在线)。
5.1 QoS
QoS是网络的一种安全机制, 是用来解决网络延迟和阻塞等问题的一种技术。
QoS中译:质量服务
质量:通讯质量,即 “消息的可靠性”。
服务:保证消息可靠的机制。
QoS等级1:至少0次,只管发,不管收。
QoS等级2:至少1次。
QoS等级3:刚好1次,保证相同的消息只接收一条。
5.2 Topic
上面提到的 过滤规则
是 Topic
。
MQTT 的 Topic 有层级结构,并且支持通配符 +
和 #
:
+
是匹配单层的通配符。比如news/+
可以匹配news/sports
,news/+/basketball
可匹配到news/sports/basketball
。#
是一到多层的通配符。比如news/#
可以匹配news
、news/sports
、news/sports/basketball
以及news/sports/basketball/x
等等。
MQTT的主题是不要预先创建的,发布者发送消息到某个主题、或者订阅者订阅某个主题的时候,Broker 就会自动创建这个主题。
5.3 带宽消耗最小化
MQTT协议将协议本身占用的额外消耗最小化,消息头部最小只需要占用 2 个字节。
MQTT协议是应用层协议,需要借助TCP/IP协议进行传输,类似HTTP协议。
5.4 MQTT的消息格式
消息格式 | |
---|---|
固定长度头部,2 个字节 | MQTT协议分很多种类型,如连接,发布,订阅,心跳等。所有消息类型里都有。 |
可变长度头部 | 可变头部不是可选的意思,而是指这部分在有些协议类型中存在,在有些协议中不存在。 |
Payload消息载体 | 就是消息内容。与可变头一样,在有些协议类型中有消息内容,有些协议类型中没有消息内容。 |
固定头包含两部分内容,首字节(字节1)和剩余消息报文长度(1-4字节)。
可变头部在固定头部和消息内容之间,其内容根据报文类型不同而不同。
Payload意思是消息载体的意思,如PUBLISH的Payload就是指消息内容。而CONNECT的Payload则包含Client Identifier,Will Topic,Will Message,Username,Password等信息。
报文类型 | 数据方向 | 描述 | 包含可变头 | 包含Payload |
---|---|---|---|---|
Reserved | 禁止 | 保留 | ||
CONNECT | 客户端向服务端 | 客户端连接请求服务端 | YES | |
CONNACK | 服务端到客户端 | 连接报文确认 | ||
PUBLISH | 两个方向都允许 | 发布消息 | YES(QoS>0) | 可选 |
PUBACK | 两个方向都允许 | QoS 1消息发布收到确认 | YES | |
PUBREC | 两个方向都允许 | 发布收到(保证交付第一步) | YES | |
PUBAEL | 两个方向都允许 | 发布释放(保证交付第二步) | YES | |
PUBCOMP | 两个方向都允许 | QoS 2消息发布完成(保证交付第三步) | YES | |
SUBSCRIBE | 客户端向服务端 | 客户端订阅请求 | YES | YSE |
SUBACK | 服务端向客户端 | 订阅请求报文确认 | YES | YES |
UNSUBSCRIBE | 客户端到服务端 | 客户端取消订阅请求 | YES | YES |
UNSUBACK | 服务端到客户端 | 取消订阅报文确认 | YES | |
PINGREQ | 客户端到服务端 | 心跳请求 | ||
PINGRESP | 客户端到客户端 | 心跳响应 | ||
DISCONNECT | 客户端到服务端 | 客户端断开连接 | ||
Reserved | 禁止 | 保留 |
5.5 会话保持
MQTT 没有假设设备或 Broker 使用了 TCP 的保活机制,而是设计了协议层的保活机制。
在 CONNECT 报文里可设置 Keepalive 字段,来设置保活心跳包 PINGREQ/PINGRESP 的发送时间间隔。
当长时间无法收到设备的 PINGREQ 的时候,Broker 就会认为设备已经下线。
总的来说,Keepalive 有两个作用:
发现对端死亡或者网络中断
在长时间无消息交互的情况下,保持连接不被网络设备断开
对于那些想要在重新上线后,重新收到离线期间错过的消息的设备,MQTT 设计了持久化连接。
在 CONNECT 报文里可设置 CleanSession 字段为 False,则 Broker 会为终端存储:
- 设备所有的订阅
- 还未被设备确认的 QoS1 和 QoS 消息
- 设备离线时错过的消息
6. MQTT协议中的方法
MQTT协议中定义了一些方法(也被称为动作),来于表示对确定资源所进行操作。这个资源可以代表预先存在的数据或动态生成数据,这取决于服务器的实现。
- Connect。等待与服务器建立连接。
- Disconnect。等待MQTT客户端完成所做的工作,并与服务器断开TCP/IP会话。
- Subscribe。等待完成订阅。
- UnSubscribe。等待服务器取消客户端的一个或多个topics订阅。
- Publish。MQTT客户端发送消息请求,发送完成后返回应用程序线程。
7. MQTT的优势
优势 | 对比 |
---|---|
低协议开销 | 对于 HTTP,为每个新请求消息重新建立 HTTP 连接会导致重大的开销。MQ 和 MQTT 所使用的永久连接显著减少了这一开销。 |
对不稳定网络的容忍 | HTTP 无法原生地实现此目的,需要客户端重试编码,这可能增加幂等性问题。 |
客户端平台差异 | HTTP 和 MQTT 客户端都已在大量平台上实现。MQTT 的简单性有助于以极少的精力在额外的客户端上实现 MQTT。 |
低功耗 | MQTT 是专门针对低功耗目标而设计的。HTTP 的设计没有考虑此因素,因此增加了功耗。 |
推送通知 | HTTP 只允许使用一种称为COMET 的方法,使用持久的 HTTP 请求来执行推送。从客户端和服务器的角度讲,此方法都很昂贵。 |
转载:https://blog.csdn.net/TheNew_One/article/details/117327391