MQTT协议学习(3.1.1版本)
本文为个人学习笔记,存在错误或理解不当的地方欢迎指正!
MQTT基础知识
MQTT 术语
名称 | 含义 | |
---|---|---|
Application Message | 应用消息 | MQTT协议通过网络传输应用数据。应用消息通过MQTT传输时,它们有关联的服务质量(QoS)和主题(Topic) |
Client | 客户端(一般云下设备为客户端) | 发布应用消息给其它相关的客户端;订阅以请求接受相关的应用消息;取消订阅以移除接受应用消息的请求;从服务端断开连接 |
Server | 服务器(作为发送消息的客户端和请求订阅的客户端之间的中介) | 接受来自客户端的网络连接;接受客户端发布的应用消息;处理客户端的订阅和取消订阅请求;转发应用消息给符合条件的已订阅客户端 |
Subscription | 订阅 | 订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。 |
Topic Name | 主题名 | 附加在应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的一个副本给每一个匹配的客户端订阅。 |
Topic Filter | 主题过滤器 | 订阅中包含的一个表达式,用于表示相关的一个或多个主题。主题过滤器可以使用通配符。 |
Session | 会话 | 客户端和服务端之间的状态交互。一些会话持续时长与网络连接一样,另一些可以在客户端和服务端的多个连续网络连接间扩展。 |
MQTT Control Packet | 控制报文 | 通过网络连接发送的信息数据包。MQTT规范定义了十四种不同类型的控制报文,其中一个 (PUBLISH报文) 用 于传输应用消息。 |
数据表示 Data representations
整数数值 Integer data values:整数数值是16位,使用大端序(big-endian,高位字节在低位字节前面)
UTF-8编码字符串 UTF-8 encoded strings:控制报文中的文本字段编码为UTF-8格式的字符串,每一个字符串都有一个两字节的长度字段作为前缀,两字节的前缀给出这个字符串UTF-8编码的字节数(字符串大小不能超过 65535字节)
发送汉字时,需要注意编译器是GBK编码还是UTF-8编码
MQTT控制报文格式 MQTT Control Packet format
MQTT协议通过交换预定义的MQTT控制报文来通信
固定报头 Fixed header
固定报头格式
MQTT控制报文的类型 MQTT Control Packet type
固定报头第1个字节的剩余的4位 [3-0]包含每个MQTT控制报文类型特定的标志
剩余长度 Remaining Length
剩余长度(Remaining Length)表示当前报文剩余部分的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。
剩余长度字段使用一个可变长度编码方案,对小于128的值它使用单字节编码。更大的值按下面的方式处理。低7位有效位用于编码数据,最高有效位是标志位,用于指示是否有更多的字节。因此每个字节可以编码128个数值和一个延续位(continuation bit)。剩余长度字段最大4个字节。每个字节的低7位用于编码数据,最高位是标志位
可变报头 Variable header
某些MQTT控制报文包含一个可变报头部分。它在固定报头和负载之间,可变报头部分包含一个两字节的报文标识符字段,这些报文是
PUBLISH(QoS > 0时), PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCIBE,UNSUBACK。
有效载荷 Payload
某些MQTT控制报文在报文的最后部分包含一个有效载荷。对于 PUBLISH来说有效载荷就是应用消息。
CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE控制报文需要有效载荷,PUBLISH控制报文可选。
MQTT控制报文 MQTT Control Packets
控制报文类别 | 功能 |
---|---|
CONNECT 连接服务端 | 客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CONNECT报文。 |
CONNACK 确认连接请求 | 服务端发送CONNACK报文响应从客户端收到的CONNECT报文。服务端发送给客户端的第 一个报文必须是CONNACK。 |
PUBLISH 发布消息 | PUBLISH控制报文是指从客户端向服务端或者服务端向客户端传输一个应用消息。 |
PUBACK 发布确认 | PUBACK报文是对QoS 1等级的PUBLISH报文的响应。 |
PUBREC 发布收到(QoS 2,第一步) | PUBREC报文是对QoS等级2的PUBLISH报文的响应。它是QoS 2等级协议交换的第二个报文 |
PUBREL 发布释放(QoS 2,第二步) | PUBREL报文是对PUBREC报文的响应。它是QoS 2等级协议交换的第三个报文。 |
PUBCOMP 发布完成(QoS 2,第三步)) | PUBCOMP报文是对PUBREL报文的响应。它是QoS 2等级协议交换的第四个也是最后一个报文。 |
SUBSCRIBE 订阅主题 | 客户端向服务端发送SUBSCRIBE报文用于创建一个或多个订阅。每个订阅注册客户端关心的一个或多个主题。为了将应用消息转发给与那些订阅匹配的主题,服务端发送PUBLISH报文给客户端。SUBSCRIBE报文也(为每个订阅)指定了最大的QoS等级,服务端根据这个发送应用消息给客户端。 |
SUBACK 订阅确认 | 服务端发送SUBACK报文给客户端,用于确认它已收到并且正在处理SUBSCRIBE报文。 |
UNSUBSCRIBE 取消订阅 | 客户端发送UNSUBSCRIBE报文给服务端,用于取消订阅主题。 |
UNSUBACK 取消订阅确认 | 服务端发送UNSUBACK报文给客户端用于确认收到UNSUBSCRIBE报文。 |
PINGREQ 心跳请求 | 客户端发送PINGREQ报文给服务端的。用于:1、 在没有任何其它控制报文从客户端发给服务的时,告知服务端客户端还活着。2、 请求服务端发送 响应确认它还活着。3、使用网络以确认网络连接没有断开。 |
PINGRESP 心跳响应 | 服务端发送PINGRESP报文响应客户端的PINGREQ报文。表示服务端还活着。 |
DISCONNECT 断开连接 | DISCONNECT报文是客户端发给服务端的最后一个控制报文。表示客户端正常断开连接。 |
CONNECT
CONNECT 连接服务端 :报文的可变报头按下列次序包含四个字段:协议名(Protocol Name),协议级别
(Protocol Level),连接标志(Connect Flags)和保持连接(Keep Alive)。
- 连接标志 Connect Flags:连接标志字节包含一些用于指定MQTT连接行为的参数
- 清理会话 Clean Session):mqtt客户端接入mqtt服务器时,选择是否继续之前的会话。
-
清理会话标志设置为1的客户端不会收到旧的应用消息,而且在每次连接成功后都需要重新订阅任何相关的主题。清理会话标志设置为0的客户端会收到所有在它连接断开期间发布的QoS 1和QoS 2级别的消息。因此,要确保不丢失连接断开期间的消息,需要使用QoS 1或 QoS 2级别,同时将清理会话标志设置为0。
- 遗嘱标志 Will Flag: >遗嘱标志(Will Flag)被设置为1,网络连接关闭时,服务端必须发布这个网络连接关闭时,服务端必须发布这个
遗嘱消息,除非服务端收到DISCONNECT报文时删除了这个遗嘱消息遗嘱消息,除非服务端收到DISCONNECT报文时删除了这个遗嘱消息 - 用户名标志 User Name Flag:如果用户名(User Name)标志被设置为1,有效载荷中必须包含用户名字段。
- 密码标志 Password Flag:如果密码(Password)标志被设置为1,有效载荷中必须包含密码字段。
- 保持连接 Keep Alive:客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控
制报文可以发送,客户端必须发送一个PINGREQ报文。如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文,它必须断开客户端的网络连接,认为网络连接已断开 - 有效载荷 Payload:包含 客户端标识符 Client Identifier;遗嘱主题 Will Topic;遗嘱消息 Will Message;用户名 User Name;密码 Password
- 响应Response
PUBLISH
PUBLISH 发布消息 :如果重发标志DUP被设置为0,表示这是客户端或服务端第一次请求发送这个PUBLISH报文。如果DUP标志被设置为1,表示这可能是一个早前报文请求的重发,对于QoS 0的消息,DUP标志必须设置为0。
- 重发标志 DUP
- 服务质量等级 QoS
- 保留标志 RETAIN:果客户端发给服务端的PUBLISH报文的保留(RETAIN)标志被设置为1,服务端必须存储
这个应用消息和它的服务质量等级(QoS)。客户端发送RETAIN=1的消息,服务端将其保留位问候消息,当新客户订阅相关主题时,服务端将信息发送给订阅者。 - 主题名 Topic Name:用于识别有效载荷数据应该被发布到哪一个信息通道。PUBLISH报文中的主题名不能包含通配符,字母的大写与小写对应不同Topic。
- 报文标识符 Packet Identifier:只有当QoS等级是1或2时,报文标识符(Packet Identifier)字段才能出现在PUBLISH报文
中。 - 有效载荷 Payload:包含将被发布的应用消息。数据的内容和格式是应用特定的(纯文本字符串、JSON字符串)。
- 响应Response
- 动作 Actions:客户端使用PUBLISH报文发送应用消息给服务端,目的是分发到其它订阅匹配的客户端。服务端使用PUBLISH报文发送应用消息给每一个订阅匹配的客户端。
SUBSCRIBE
SUBSCRIBE 订阅主题 :客户端向服务端发送SUBSCRIBE报文用于创建一个或多个订阅。为了将应用消息转发给与那些订阅匹配的主题,服务端发送PUBLISH报文给客户端。
- 有效载荷 Payload:SUBSCRIBE报文的有效载荷包含了一个主题过滤器列表,它们表示客户端想要订阅的主题。每一个过滤器后面跟着一个字节,这个字节被叫做 服务质量要求(Requested QoS)。它给出了服务端向客户端发送应用消息所允许的最大QoS等级。SUBSCRIBE报文的有效载荷必须包含至少一对主题过滤器 和 QoS等级字段组合。
- 响应Response:服务端收到客户端发送的一个SUBSCRIBE报文时,必须使用SUBACK报文响应。SUBACK报文必须和等待确认的SUBSCRIBE报文有相同的报文标识符 。服务端发送给客户端的SUBACK报文对每一对主题过滤器 和QoS等级都必须包含一个返回
码。
PINGREQ
PINGREQ 心跳请求 :
- 在没有任何其它控制报文从客户端发给服务的时,告知服务端客户端还活着。
- 请求服务端发送 响应确认它还活着。
- 使用网络以确认网络连接没有断开。
PINGRESP
PINGRESP 心跳响应 :服务端发送PINGRESP报文响应客户端的PINGREQ报文。表示服务端还活着。保持连接(Keep Alive)处理中用到这个报文。
MQTT Qos
Qos:质量服务
质量:通讯质量,即 “消息的可靠性”。
服务:保证消息可靠的机制。
Qos等级 | 功能 |
---|---|
Qos0 | 只管发送,不管对方能否接到,可靠性基于TCP |
Qos1 | 发送端发送之后没有收到对应的PUBACK,就会继续重试,直到接收到接收端发送的 PUBACK 为止,因为重传的原因,接收端有可能会收到重复的消息 |
Qos2 | 发送端发送的一条消息,接收端确保能收到而且只收到一次,发送失败重试的同时保证接收端不会因为消息重传而收到重复的消息。 |
发布端和订阅端都有Qos等级,但订阅端的Qos等级要基于发布端的Qos等级。
组合为
P(发布端 ) | S(订阅端) |
---|---|
P(QOS0) | S(QOS0) |
P(QOS1) | S(QOS0) |
P(QOS1) | S(QOS1) |
P(QOS2) | S(QOS0) |
P(QOS2) | S(QOS1) |
P(QOS2) | S(QOS2) |
ps:
- 应用不能使用
$
字符开头的主题 - 斜杠
/
用于分割主题的每个层级,为主题名提供一个分层结构 - 如果服务端或客户端遇到了协议违规的行为,它必须关闭传输这个协议违规控制报文的网络连接