MQTT协议学习笔记
MQTT协议
MQTT协议的概念
MQTT协议,全称Message Queue Telemetry Transport,即消息队列遥测传输协议,是一种基于发布/订阅的轻量级通讯协议,适用于条件较差的网络环境,如:网络延迟高、带宽低、通信讯号不稳定等情况。
MQTT协议的特点
-
构建于TCP/IP协议之上
TCP/IP参考模型可分为四层:应用层、传输层、网络层、链路层。TCP、UDP协议均属于传输层,MQTT运行与TCP之上,属于应用层协议,只要支持TCP/IP协议栈的地方都可应用MQTT。 -
基于C-S架构的消息发布/订阅
提供一对多的消息发布,作为客户端之间的中间介质,解除应用程序的耦合。 -
对负载内容屏蔽的消息传输
-
使用TCP连接进行数据推送
-
三种消息发布QoS
- QoS 0:至多一次。服务器只推送1次,至于客户端是否收到,收到的消息是否正确,数据是否有所丢失,都不管。
- QoS 1:至少一次。客户端收到服务器的推送后要回复一个PUBACK告诉服务器已收到,否则服务器会认为Client未收到推送,隔一段时间后重新发送,直到对方回复PUBACK。
- QoS 2:只发一次。保证数据包到达目的地,且不会出现重复。服务器发送数据包,客户端接收后回复PUBREC(收到发布消息)报文,服务器存储PUBREC中的报文标识符,发送PUBREL(释放发布消息)。
MQTT协议通信流程
1.消息类型
名称 | 值 | 流向 | 说明 |
---|---|---|---|
CONNECT | 1 | C -> S | 客户端连接请求 |
CONNACK | 2 | S -> C | 服务端确认连接 |
PUBLISH | 3 | C <-> S | 发布消息 |
PUBACK | 4 | C <-> S | QoS1消息确认 |
PUBREC | 5 | C <-> S | QoS2收到消息(保证传输step1) |
PUBREL | 6 | C <-> S | QoS2释放消息(保证传输step2) |
PUBCOMP | 7 | C <-> S | QoS2完成消息(保证传输step3) |
SUBSCRIBE | 8 | C -> S | 订阅消息 |
SUBACK | 9 | S -> C | 订阅确认 |
UNSUBSCRIBE | 10 | C -> S | 取消订阅 |
UNSUBACK | 11 | S -> C | 取消订阅确认 |
PINGREQ | 12 | C -> S | 连接保活请求 |
PINGRESP | 13 | S -> C | 保活回应 |
DISCONNECT | 14 | C -> S | 断开连接 |
注:值为0和15表示保留
2.MQTT控制报文
MQ控制报文由三部分组成:固定报头+可变报头+有效载荷
固定报头 | 所有控制报文都包含 |
---|---|
可变报头 | 部分报文包含 |
有效载荷 | 部分报文包含 |
- 固定报头格式
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Byte 1 | MQTT控制报文类型 | 控制报文类型的标志位 | ||||||
Byte 2 | 剩余长度 |
注:固定报头Byte1的高四位是表1中消息类型的值,以二进制数表示。低四位是报文类型的标志位。
- 可变报头
可变报头在固定报头和负载之间。可变报头的报文标识符字段存在于在多个类型的报文里。
很多控制报文的可变报头部分包含一个两字节的报文标识符字段。这些报文是QoS > 0时的PUBLISH,PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE, SUBACK,UNSUBSCRIBE,UNSUBACK。SUBSCRIBE,UNSUBSCRIBE和PUBLISH(QoS>0)控制报文必须包含一个非零的16位报文标识符。客户端每次发送一个新的这些类型的报文时都必须分配一个当前未使用的报文标识符。如果一个客户端要重发这个特殊的控制报文,在随后重发那个报文时,它必须使用相同的标识符。当客户端处理完这个报文对应的确认后,这个报文标识符就释放可重用。发送一个QoS 0的PUBLISH报文时,相同的条件也适用于服务端。
即uuid,标识会话,当标识符一致时表示在同一会话中。
3.Wireshark抓包
从报文可看到,Client与MQ Server首先做三次TCP握手连接,建立连接成功后,Client给MQ服务器发送connect登录请求,服务器回应一个ACK表示登录成功。协议消息中可看出,登录请求报文的QoS=0,即只推送一次消息。
客户端向MQ服务器发布消息,发送publish报文,可从报文信息中看到,QoS=1,即至少发送1次,服务器收到后回复Publish Ack确认报文,否则一段时间后发布方没收到确认将进行重传。另外,报文中可看出MQTT固定报文头0x32 = 00110010,3表示消息类型为Publish(表1能查到)。此处Publish报文发布新Portal消息,AC程序主动发送的无感知报文。
订阅请求报文Subscribe Request。上图1报文为客户端向MQ服务器请求订阅YS保活Topic消息。图2为二级AC上线后的订阅请求,可看到MQTT报文有效载荷包含二级AC的MAC地址。收到消息后对端回复Subscribe Ack,QoS=1。