一、MQTT协议简介

1. MQTT协议概念

  • MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于订阅/发布(Subscribe/Publish)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,在1999年,由IBM发布;
  • MQTT最大优点在于,可以以极少的代码和有限的带宽,位连接远程设备提供实时可靠的消息服务;

2.MQTT基本格式

固定报头(fixed header) + 可变报头(variable header) + 荷载(payload)

(1)固定报头(所有类型的MQTT报文都有)

  • 固定报头的构成:
    • 消息类型和标志位(1字节)
      • 前4位(4~7位),表示消息类型(共14种),即定义消息的功能,例如:
        在这里插入图片描述

      • 后4位(0~3位):标志位(不同的消息类型有不同的定义),例如:
        在这里插入图片描述
        DUP:为0时表示PUBLISH报文是第1次发送,为1时表示PUBLISH报文是重发报文;
        QoS表示通信质量,共有三个等级:
        QoS0(最多发送一次);
        QoS1(至少发送一次,未收到PUBACK报文时,可能重复发送);
        QoS2(只发送一次,并且保证报文有发送到);
        RETAIN:设置Retain=1,服务器会将该消息持久化存储,并在后续有新订阅者订阅该主题时,将消息重新发送给新订阅者;设置Retain=0,消息仅实时传递给当前在线的订阅者,不存储(仅在PUBLISH消息中有效);

    • 剩余长度(1~4字节)
      • 表示整个消息剩余部分(可变报头+荷载,即不包含固定报头)的长度;
      • 编码方式:
        • 每个字节低7位表示存储数值;最高位为1,表示后面还有更多字节,为0,表示当前是最后一个字节;
        • 可表示的最大值为2^28 -1
        • 例如:剩余长度为3个字节:
          0b 1110 0111 = 0xE7 —> 0x67
          0b 1000 1101 = 0x8D —>0x0D
          0b 0001 0001 = 0x11 —>0x11
          则剩余长度值len = 0x67 + (0x0D << 7) + (0x11 << 14)

(2)可变报头、荷载(部分类型的MQTT报文有),各报文情况如下

1) CONNECT与CONNECTACK报文(连接和连接回复报文):
  • CONNECT报文报文是客户端向服务器发起请求连接的报文------>服务器会验证其中的消息并返回CONNECTACK报文告知客户端结果;
  • CONNECT报文包含:固定包头 + 可变包头 + 消息荷载;
    在这里插入图片描述
    协议名长度:高字节固定为0,低字节为0x04或0x06;
    协议名:MQTT或MQIsdp(3.1.1以后的版本就是MQTT);
    协议等级:3(MQTT3.1)、4(MQTT3.1.1)、5(MQTT5.0);
    连接标志:用于指示payload荷载由哪些内容组成;
    保持连接时间(即保活时间):一般为30~1200秒;
    • 连接标志:
      在这里插入图片描述
      连接标志对应位为1,则在payload荷载中就包含对应的内容;
      如果连接标志包含所有内容,payload荷载必须按 客户端标识符 + 遗嘱主题 + 遗嘱消息 + 用户名 + 密码这个顺序排列;
      遗嘱功能:当服务器检测到客户端非正常断开连接时,就会向客户端遗嘱主题发布相应的遗嘱消息;
      Clean Session:清理会话标志位;CleanSession=1,客户端与服务器的会话在断开后不保留,服务器会清除该客户端的所有未处理消息、订阅关系等状态;CleanSession=0,客户端与服务器的会话在断开后保留,服务器会维护客户端的订阅关系、未送达的 QoS 1/2 消息等状态,以便客户端重新连接时恢复;
  • CONNECTACK报文包含:固定包头 + 可变包头;
    在这里插入图片描述
    会话存在标志(Session Present):
    • 当客户端在 CONNECT 报文中把 CleanSession 标志设为 0,并且服务器中存在该客户端之前的会话时,Session Present 标志为 1。这表明服务器已恢复该客户端之前的会话,客户端可以继续使用之前的订阅信息和未处理完的消息;
    • 若客户端在 CONNECT 报文中将 CleanSession 标志设为 0,且服务器中不存在该客户端之前的会话,Session Present 标志为 0。这表明客户端请求恢复会话,但服务器没有找到对应会话,此次连接是一个新的会话开始;
    • 当客户端在 CONNECT 报文中将 CleanSession 标志设为 1,服务器返回的 CONNECTACK 报文中 Session Present 标志为 0,意味着服务器不会保留与该客户端相关的会话状态,客户端和服务器之间建立的是全新会话;
2)PUBLISH与SUBSCRIBE报文(发布和订阅报文)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、ESP32 连接MQTT服务器

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐