MQTT协议学习笔记

MQTT协议

MQTT固定报头(Fixed Header)

每个MQTT报文都包含至少2个字节的固定报头

消息类型(Message Type)
重发标识(Dup Flag)
质量等级(QoS)
保持标识(Retain Flag)

Bit76543210
byte1消息类型(Message Type)重发标识(Dup Flag)质量等级(QoS level)保持标识(Retain Flag)
byte2more byteRemaining Length
[byte3]more byte
[byte4]more byte
[byte5]more byte
[byte6]可变报头(Variable Header)
[byte7]
byte...有效载荷Payload

报文类型(Message Type)

名称方向猫叔
Reserved0禁止保留值
CONNECT1客户端→服务端客户端请求连接服务端
CONNACK2服务端→客户端连接报文确认
PUBLISH3双向允许发布消息
PUBACK4双向允许QoS 1消息发布收到确认
PUBREC5双向允许发布收到(保证交付第一步)
PUBREL6双向允许发布释放(保证交付第二步)
PUBCOMP7双向允许QoS 2消息发布完成(保证交互第三步)
SUBSCRIBE8客户端→服务端客户端订阅请求
SUBACK9服务端→客户端订阅请求报文确认
UNSUBSCRIBE10客户端→服务端客户端取消订阅请求
UNSUBACK11服务端→客户端取消订阅报文确认
PINGREQ12客户端→服务端心跳请求
PINGRESP13服务端→客户端心跳响应
DISCONNECT14客户端→服务端客户端断开连接
Reserved15禁止保留值

标识符

固定报头第一个字节的后4位为标识符,
对于PUBLISH类型的消息来说,分别表示DUP、QoS、RETAIN3个标识,
对于其他类型的消息来说,这4位为保留位,
具体的值应该符合下表的定义,如果收到非法的标识符,协议的双方应该选择关闭网络连接。

控制报文固定报头标志Bit 3Bit 2Bit 1Bit 0
CONNECTReserved0000
CONNACKReserved0000
PUBLISHUsed in MQTT 3.1.1DUP1QoS2QoS2RETAIN3
PUBACKReserved0000
PUBRECReserved0000
PUBRELReserved0010
PUBCOMPReserved0000
SUBSCRIBEReserved0010
SUBACKReserved0000
UNSUBSCRIBEReserved0010
UNSUBACKReserved0000
PINGREQReserved0000
PINGRESPReserved0000
DISCONNECTReserved0000
重发标识(Dup Flag)

对PUBLISH类型的消息来说,MQTT第1个字节的第3位表示重发标识,主要用于保证消息可靠传输,默认值为0,表示第一次发送。
当QoS为大于0时,发布的消息需要回复确认,如果客户端或服务器端没有收到确认回复则尝试重发消息,此时消息的Dup Flag被置为1(需要指出的是,该标识位不能用于检测消息的重复发送)。

总结:指明是不是重发的包

质量等级(QoS Level)

MQTT使用第1个字节第2、1位表示质量等级,具体的定义如下表所示:

QoS Level21说明解释
000至多1次(At Most Once)Sender只发一次,不关心Receiver是否收到
101至少1次(At Least Once)发多次,直到Receiver收到(Receiver可能收到多次)
210保证1次(Exactly Once)发多次,直到Receiver收到(Receiver只收到一次)
311保留值保留值

QoS0 代表,Sender 发送的一条消息,Receiver 最多能收到一次,也就是说 Sender 尽力向 Receiver 发送消息,如果发送失败,也就算了;
QoS1 代表,Sender 发送的一条消息,Receiver 至少能收到一次,也就是说 Sender 向 Receiver 发送消息,如果发送失败,会继续重试,直到 Receiver 收到消息为止,但是因为重传的原因,Receiver 有可能会收到重复的消息;
QoS2 代表,Sender 发送的一条消息,Receiver 确保能收到而且只收到一次,也就是说 Sender 尽力向 Receiver 发送消息,如果发送失败,会继续重试,直到 Receiver 收到消息为止,同时保证 Receiver 不会因为消息重传而收到重复的消息。

解析: Qos2 通过给消息加Id编号,即使发重发了,接收方也可以通过Id编号去重,需要两轮交互,第一轮保证接收方接收到消息,第二轮保证不会发送方不会再次发送消息

注意:
QoS是Sender和Receiver之间的协议,而不是Publisher和Subscriber之间的协议。换句话说,Publisher发布了一条QoS1的消息,只能保证Broker能至少收到一次这个消息;而对于Subscriber能否至少收到一次这个消息,还要取决于Subscriber在Subscibe的时候和Broker协商的QoS等级

QoS0
stepsenderdirreceiver
1Sender–(PUBLISH)–>Receiver
Qos1
stepsenderdirreceiver
1Sender–(PUBLISH)–>Receiver
2Sender<–(PUBACK)–Receiver
Qos2
stepsenderdirreceiver
1Sender–(PUBLISH)–>Receiver
2Sender<–(PUBREC)–Receiver
3Sender–(PUBREL)–>Receiver
4Sender<–(PUBCOMP)–Receiver
保持标识(Retain Flag)

MQTT报文第1字节第0位用于保持标识,服务端和客户端处理保持标识时需要满足以下规则:

i.在客户端发给服务端的PUBLISH报文中,如果RETAIN标识被设置为1,服务端必须保存改消息及其QoS,以使该报文可以被投递给订阅了对应主题的新订阅者;

ii.当新的订阅建立时,服务端必须把每一个主题保持的最近一条RETAIN消息(如果存在的话),投递给订阅者;

iii.如果服务端收到QoS为0,RETAIN标识为1的消息,服务端必须丢弃该主题下保存的所有RETAIN消息,同时保存这条QoS为0的消息,但是这条消息可以随时被丢弃;

iv.当一个新订阅建立时,服务端发给客户端的PUBLISH报文需设置RETAIN为1,其他情况服务端发给客户端的PUBLISH报文的RETAIN位都需要被置为0,不管服务端收到该PUBLISH报文时它的标识是什么;

v.当一个0字节内容的PUBLISH报文的RETAIN标识为1时,服务端会把这条消息投递给订阅了对应主题的订阅者,同时清空这个主题下保持的所有消息。需要指出的是,客户端收到的这条消息的RETAIN标识为0,服务端不会保存0字节内容的消息;

vi.当客户端向服务端发布一条RETAIN为0的PUBLISH报文时,服务端不会保存这条消息,也不会删除或者替换已经保存的RETAIN为1的消息;

剩余长度 Remaining Length

每个字节第一位如果为1,表示下一个字节也为剩余长度
最长4个字节,既如果有第四个字节,第一位必须为0

字节数最小值内存值最大值内存值算法
1 byte0x00(0x00)0x7f(0x7f)(byte1&0x7f)
2 byte0x80(0x80,0x01)0x3fff(0Xff,0x7f)(byte2&0x7f)<<7 + (byte1&0x7f)
3 byte0x4000(0x80,0x80,0x01)0x1fffff(0xff,0xff,0x7f)(byte3&0x7f)<<14 + (byte2&0x7f)<<7 + (byte1&0x7f)
4 byte0x200000(0x80,0x80,0x80,0x01)0xfffffff(0xff,0xff,0xff,0x7f)(byte4&0x7f)<<21 + (byte3&0x7f)<<14 + (byte2&0x7f)<<7 + (byte1&0x7f)

可变报头(Variable Header)

可变报头(Variable Header)

在某些类型的MQTT报文中存在位于固定报头和有效载荷之间的包含2个字节的可变报头。

具体的报文类型包括PUBLISH (QoS > 0), PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK等。

控制报文可变报头
CONNECT不需要
CONNACK不需要
PUBLISHQoS > 0需要
PUBACK需要
PUBREC需要
PUBREL需要
PUBCOMP需要
SUBSCRIBE需要
SUBACK需要
UNSUBSCRIBE需要
UNSUBACK需要
PINGREQ不需要
PINGRESP不需要
DISCONNECT不需要

有效载荷Payload

有效载荷Payload即报文的正文部分,包含Payload字段的报文类型主要如下表所示:

控制报文有效载荷
CONNECT需要
CONNACK不需要
PUBLISH可选
PUBACK不需要
PUBREC不需要
PUBREL不需要
PUBCOMP不需要
SUBSCRIBE需要
SUBACK需要
UNSUBSCRIBE需要
UNSUBACK不需要
PINGREQ不需要
PINGRESP不需要
DISCONNECT不需要
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值