MQTT报文理解

官方文档


看图更好理解
图解


报文结构

  1. 固件报头Fixed header

    1. 控制报文的类型 Control Packet type,14种有效类型: [connect, publish, subscribe,.....]

      第一个1个字节前4位,

    2. 标志Flags,

      第一个1个字节后4位,

      1. DUP 控制报文是否为重复报文,只有PUBLISH才会有DUP为1的情况,其他的报文类型都是0
    3. QoS 控制PUBLISH报文的质量等级,

      1. 最多一次(0), 发出去了就不管了

        publish

      2. 至少一次(1) ,发不出必须要等接收方回复ack,没有回复,那么就找时机重发,接收方需要处理去重

        publish - pubrec

      3. 准确一次(2),保证只发一次,需要持久化,重复消息自动去重,并且只有当接收方把消息投递出去,才算完成

        publish - pubrec - pubrel - pubcomp

    4. RETAIN,

      每个topic只有唯一的保留消息,每个client订阅的时候,会立刻读取到保留消息

      1. 如果订阅者无法与broker连接,可以通过retain消息,让订阅者下次连接订阅成功时一次接受所有的内容

      2. 发布者定时发布retain消息,订阅者可以根据retain消息的变化推测发布者状态

    5. 剩余长度 Remaining Length

      从第二个字节开始,最大长度是4个字节,低位在前,高位在后,通过每一个字节第一位[0不需要 1需要]确定是否需要继续往后继续计算,也就是最多可以存储256M, 最大值16进制为:0xFF,0xFF,0xFF,0x7F

  2. 可变报头Variable header

    可变报文部分是根据不同的报文类型,这部分的内容也不同

    比如: 连接报文会有用户名密码标识,遗嘱标识 ,是否清理会话标识等

    ​ 发布报文会有topic信息

    1. 报文标识符 PackageIdentifier 【messageId】

      2个字节最大65535

      这些报文类型需要:PUBLISH(QoS > 0), PUBACK, PUBREL, PUBCOMP, SUBSCRIBE,SUBACK, UNSUSCRIBE,UNSUBACK

      重发使用相同的标识符

      确认后释放标识符

  3. 有效载荷Payload

    这些报文类型才有payload:

    CONNECT(用户名密码,遗嘱消息,遗嘱topic,客户端标识),

    PUBLISH(可有可无,根据实际情况),

    SUBSCRIBE(订阅的topic信息集合),

    SUBACK(按顺序返回的订阅的topic的报文质量等级集合)

    UNSUBSCRIBE(取消订阅的topic信息集合)

报文类型处理逻辑(接收方的处理逻辑)

CONNECT 连接服务端 客户端--服务端

  1. 报文解析错误:
    1. 如果报文解析错误,连接失败
    2. 如果解析的报文标识符不合法,连接失败
  2. 报文解析成功
    1. 如果报文标识符不存在,连接失败
    2. 如果用户密码验证失败,连接失败
    3. 如果是会话中已经存在该连接,说明是发送重复的连接报文
      1. 如果之前保存的会话信息,cleanSession == true,需要清空保存的session,订阅信息,需要重发的发布QoS1报文,需要重发的发布的QoS2的报文
      2. 关闭之前的保存的会话
    4. 检查心跳包,将已经存在的心跳包的间隔时间,更新成客户端指定的时间
    5. 如果连接报文中存在遗嘱消息,需要将遗嘱消息保存在本次连接的会话对象中
      1. 连接成功,保存会话信息
      2. 连接成功,回会CONNACK报文给客户端
    6. 如果本次连接的报文cleanSession == false,也就是不清理会话,如果是客户端重连的,可能存在服务端有部分信息没有发送出去,需要重新发送给该客户端
      1. 重发QoS1的未完成的消息
      2. 重发QoS2的未完成的消息

CONNACK 确认连接请求 服务端--客户端

​ 1. 客户端确认连接成功

PUBLISH 发布消息 双向

客户端发送给服务端,是为了将报文分发到其他订阅匹配的客户端

服务端发送给客户端,是为了发消息给匹配订阅的客户端

1. 根据不同的质量等级进行不同的回复报文
    1. QoS 0 直接publish消息即可
    2. QoS 1 PUBLISH消息之后,还需要回复PUBACK给来源客户端
    3. Qos 2 PUBLISH消息之后,还需要回复PUBREC给来源客户端 (后续客户端端发送PUBREL,再服务端发送PUBCOMP完成整个生命周期)
2. 如果是保留消息,需要覆盖之前保存的保留消息

PUBACK 发布确认 双向

1. 带着messageId回复发布方,通知发布成功

PUBAREC 发布收到 双向

​ 1. 带着messageId回复发布方,通知收到了发布报文

PUBREL 发布释放 双向

​ 1. 带着messageId回复接收方,可以释放报文

PUBCOMP 发布完成 双向

​ 1. 带着messageId回复发布方,可以发布完成了

SUBSCRIBE 订阅主题 客户端--服务端

1.  根据订阅的主题列表,
    1.  保存订阅信息
    2.  回复SUBACK,按顺序返回订阅报文中的报文质量等级集合
2.  根据订阅的主题,处理服务端保留信息,立即PUBLISH给客户端

SUBACK 订阅确认 服务端-- 客户端

1.  客户端确认订阅成功

UNSUBSCRIBE 取消订阅 客户端--服务端

  1. 移除掉该客户端保存的订阅主题
  2. 回复UNSUBACK报文

UNSUBACK 订阅确认 服务端-- 客户端

  1. 客户端确认取消订阅成功

PINGREQ 心跳请求 客户端--服务端

  1. 返回客户端PINGRESP报文

PINGRESP 心跳响应 服务端--客户端

  1. 收到报文确认服务端正常

你可能感兴趣的:(MQTT报文理解)