回答:
报文是网络中交换和传输的数据单元,也是网络传输的单元。报文包含了将要发送的完整的数据信息,其长短不需一致。报文在传输过程中会不断地封装成分组、包、帧来传输,封装的方式就是添加一些控制信息组成的首部,那就是报文头。
mqtt协议报文结构
固件报头Fixed header
最多一次(0), 发出去了就不管了
至少一次(1),发出必须要等接收方回复ack,没有回复,那么就找时机重发,接收方需要处理去重
准确一次(2),保证只发一次,需要持久化,重复消息自动去重,并且只有当接收方把消息投递出去,才算完成
控制报文的类型 Control Packet type,14种有效类型: [connect, publish, subscribe,.....]
第一个1个字节前4位,
标志Flags,
第一个1个字节后4位,
DUP 控制报文是否为重复报文,只有PUBLISH才会有DUP为1的情况,其他的报文类型都是0
QoS 控制PUBLISH报文的质量等级,
publish
publish - pubrec
publish - pubrec - pubrel - pubcomp
RETAIN,
每个topic只有唯一的保留消息,每个client订阅的时候,会立刻读取到保留消息
如果订阅者无法与broker连接,可以通过retain消息,让订阅者下次连接订阅成功时一次接受所有的内容
发布者定时发布retain消息,订阅者可以根据retain消息的变化推测发布者状态
剩余长度 Remaining Length
从第二个字节开始,最大长度是4个字节,低位在前,高位在后,通过每一个字节第一位[0不需要,1需要]确定是否需要继续往后继续计算,也就是最多可以存储256M, 最大值16进制为:0xFF,0xFF,0xFF,0x7F
可变报头Variable header
可变报文部分是根据不同的报文类型,这部分的内容也不同
比如: 连接报文会有用户名密码标识,遗嘱标识,是否清理会话标识等,发布报文会有topic信息
报文标识符 PackageIdentifier [messageId]
标识符作用:
2个字节最大65535
这些报文类型需要:PUBLISH(QoS > 0), PUBACK, PUBREL, PUBCOMP, SUBSCRIBE,SUBACK, UNSUSCRIBE,UNSUBACK
重发使用相同的标识符
确认后释放标识符
有效载荷Payload
以下这些报文类型才有payload:
CONNECT(用户名密码,遗嘱消息,遗嘱topic,客户端标识),
PUBLISH(可有可无,根据实际情况),
SUBSCRIBE(订阅的topic信息集合),
SUBACK(按顺序返回的订阅的topic的报文质量等级集合)
UNSUBSCRIBE(取消订阅的topic信息集合)
报文类型处理逻辑(接收方的处理逻辑)
CONNECT 连接服务端 客户端--服务端
报文解析错误:
如果报文解析错误,连接失败
如果解析的报文标识符不合法,连接失败
报文解析成功
重发QoS1的未完成的消息
重发QoS2的未完成的消息
连接成功,保存会话信息
连接成功,回会CONNACK报文给客户端
如果之前保存的会话信息,cleanSession == true,需要清空保存的session,订阅信息,需要重发的发布QoS1报文,需要重发的发布的QoS2的报文
关闭之前的保存的会话
如果报文标识符不存在,连接失败
如果用户密码验证失败,连接失败
如果是会话中已经存在该连接,说明是发送重复的连接报文
检查心跳包,将已经存在的心跳包的间隔时间,更新成客户端指定的时间
如果连接报文中存在遗嘱消息,需要将遗嘱消息保存在本次连接的会话对象中
如果本次连接的报文cleanSession == false,也就是不清理会话,如果是客户端重连的,可能存在服务端有部分信息没有发送出去,需要重新发送给该客户端
CONNACK 确认连接请求 服务端--客户端
客户端确认连接成功
PUBLISH 发布消息 双向
客户端发送给服务端,是为了将报文分发到其他订阅匹配的客户端
服务端发送给客户端,是为了发消息给匹配订阅的客户端
根据不同的质量等级进行不同的回复报文
QoS 0 直接publish消息即可
QoS 1 PUBLISH消息之后,还需要回复PUBACK给来源客户端
Qos 2 PUBLISH消息之后,还需要回复PUBREC给来源客户端 (后续客户端端发送PUBREL,再服务端发送PUBCOMP完成整个生命周期)
如果是保留消息,需要覆盖之前保存的保留消息
PUBACK 发布确认 双向
带着messageId回复发布方,通知发布成功
PUBAREC 发布收到 双向
带着messageId回复发布方,通知收到了发布报文
PUBREL 发布释放 双向
带着messageId回复接收方,可以释放报文
PUBCOMP 发布完成 双向
带着messageId回复发布方,可以发布完成了
SUBSCRIBE 订阅主题 客户端--服务端
根据订阅的主题列表,
保存订阅信息
回复SUBACK,按顺序返回订阅报文中的报文质量等级集合
根据订阅的主题,处理服务端保留信息,立即PUBLISH给客户端
SUBACK 订阅确认 服务端-- 客户端
客户端确认订阅成功
UNSUBSCRIBE 取消订阅 客户端--服务端
移除掉该客户端保存的订阅主题
回复UNSUBACK报文
UNSUBACK 订阅确认 服务端-- 客户端
客户端确认取消订阅成功
PINGREQ 心跳请求 客户端--服务端
返回客户端PINGRESP报文
PINGRESP 心跳响应 服务端--客户端
收到报文确认服务端正常
免责声明:本网站部分文章、图片等信息来源于网络,版权归原作者平台所有,仅用于学术分享,如不慎侵犯了你的权益,请联系我们,我们将做删除处理!