跳转至

MQTT 协议文档 📡

欢迎使用 MQTT 协议文档

MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅消息传输协议,专为物联网和低带宽环境设计。

📖 协议概述

MQTT 是一种基于客户端-服务器的消息发布/订阅传输协议,由 IBM 在 1999 年开发。它已经成为物联网领域最流行的通信协议之一。

🌟 主要特性

  • 协议头最小仅2字节
  • 低带宽消耗
  • 适合资源受限设备
  • 解耦消息生产者和消费者
  • 支持一对多消息分发
  • 灵活的Topic主题系统
  • 三种服务质量等级
  • 持久会话支持
  • 遗嘱消息机制
  • 低延迟消息传递
  • 支持即时通信
  • 适合实时监控场景

🔧 协议架构

MQTT 采用客户端-服务器架构:

发布者 (Publisher) → MQTT 代理 (Broker) → 订阅者 (Subscriber)
    客户端                     服务器              客户端

核心组件

组件 角色 功能
发布者 消息生产者 向特定主题发布消息
订阅者 消息消费者 订阅感兴趣的主题接收消息
代理 消息路由器 接收、过滤和转发消息

📊 消息格式

MQTT 消息由固定头部、可变头部和有效载荷三部分组成:

固定头部 (Fixed Header)

Bit: 7  6  5  4 | 3  2  1  0
    Message Type | Flags/DUP/QoS/Retain

消息类型 (4 bits):

  • 1: CONNECT - 连接请求
  • 2: CONNACK - 连接确认
  • 3: PUBLISH - 发布消息
  • 4: PUBACK - 发布确认
  • 5: PUBREC - 发布收到
  • 6: PUBREL - 发布释放
  • 7: PUBCOMP - 发布完成
  • 8: SUBSCRIBE - 订阅请求
  • 9: SUBACK - 订阅确认
  • 10: UNSUBSCRIBE - 取消订阅
  • 11: UNSUBACK - 取消订阅确认
  • 12: PINGREQ - 心跳请求
  • 13: PINGRESP - 心跳响应
  • 14: DISCONNECT - 断开连接

可变头部 (Variable Header)

根据消息类型不同而变化的头部字段。

有效载荷 (Payload)

实际传输的数据内容。

🎯 核心消息类型详解

CONNECT - 连接请求

客户端连接到代理时发送的第一个消息。

固定头部:

  • Message Type: 1 (0x10)
  • Flags: 保留位设为0

可变头部:

  • Protocol Name: "MQTT" (6字节)
  • Protocol Level: 4 (MQTT 3.1.1)
  • Connect Flags: 连接标志位
  • Keep Alive: 心跳间隔(秒)

连接标志位:

1
2
3
Bit: 7      6      5    4    3    2    1    0
    User   Pass  Will  Will  Will  Clean  Reserved
    Name   word  Retain QoS  Flag Session

有效载荷:

  • Client ID (必选)
  • Will Topic (可选)
  • Will Message (可选)
  • Username (可选)
  • Password (可选)

CONNACK - 连接确认

代理对CONNECT消息的响应。

固定头部:

  • Message Type: 2 (0x20)

可变头部:

  • Connect Acknowledge Flags (1字节)
  • Connect Return Code (1字节)

返回码:

  • 0: 连接已接受
  • 1: 连接被拒绝,不支持的协议版本
  • 2: 连接被拒绝,标识符不合格
  • 3: 连接被拒绝,服务器不可用
  • 4: 连接被拒绝,用户名或密码错误
  • 5: 连接被拒绝,未授权

PUBLISH - 发布消息

用于发布消息到特定主题。

固定头部:

  • Message Type: 3 (0x30)
  • DUP: 重复发送标志
  • QoS: 服务质量等级
  • Retain: 保留消息标志

可变头部:

  • Topic Name: 主题名称
  • Packet Identifier: 包标识符(QoS > 0时使用)

有效载荷:

  • 实际消息内容

SUBSCRIBE - 订阅请求

客户端订阅一个或多个主题。

固定头部:

  • Message Type: 8 (0x80)

可变头部:

  • Packet Identifier: 包标识符

有效载荷:

  • 主题过滤器列表,每个包含:
  • Topic Filter: 主题过滤器
  • Requested QoS: 请求的QoS等级

UNSUBSCRIBE - 取消订阅

客户端取消订阅主题。

固定头部:

  • Message Type: 10 (0xA0)

可变头部:

  • Packet Identifier: 包标识符

有效载荷:

  • 主题过滤器列表

⚡ 服务质量等级 (QoS)

MQTT 提供三种服务质量等级:

特点:

  • 消息可能丢失
  • 无确认机制
  • 传输开销最小

适用场景:

  • 非关键数据
  • 高频传感器数据
  • 可以容忍数据丢失的场景

特点:

  • 消息不会丢失
  • 可能重复接收
  • 需要确认机制

流程:

发布者 → PUBLISH → 代理 → PUBLISH → 订阅者
发布者 ← PUBACK  ← 代理 ← PUBACK  ← 订阅者

适用场景:

  • 重要但允许重复的数据
  • 命令下发
  • 配置更新

特点:

  • 消息不会丢失
  • 不会重复接收
  • 最可靠但开销最大

流程:

1
2
3
4
发布者 → PUBLISH → 代理 → PUBLISH → 订阅者
发布者 ← PUBREC  ← 代理 ← PUBREC  ← 订阅者
发布者 → PUBREL  → 代理 → PUBREL  → 订阅者  
发布者 ← PUBCOMP ← 代理 ← PUBCOMP ← 订阅者

适用场景:

  • 关键业务数据
  • 金融交易
  • 不允许重复的精确数据

🔍 主题系统 (Topic)

主题语法

主题是UTF-8字符串,用于消息路由:

1
2
3
sensors/temperature/room1
home/livingroom/light/switch
vehicles/car1/gps/location

主题层级

使用 / 分隔主题层级:

级别1 / 级别2 / 级别3

通配符

匹配单个层级:

1
2
3
4
订阅: home/+/temperature
匹配: home/livingroom/temperature ✓
匹配: home/bedroom/temperature ✓
不匹配: home/livingroom/kitchen/temperature ✗

匹配多个层级:

1
2
3
4
订阅: sensors/#
匹配: sensors/temperature ✓
匹配: sensors/humidity/room1 ✓  
匹配: sensors/light/switch/status ✓

通配符使用限制

  • # 必须是主题的最后一个字符
  • +# 只能用于订阅,不能用于发布
  • 主题不能以 / 开头(某些代理可能允许)

🛡️ 会话管理

清洁会话 (Clean Session)

  • Clean Session = 1: 不保留会话状态
  • Clean Session = 0: 保留会话状态(离线消息队列、订阅信息等)

持久会话特性

  • 离线消息队列
  • 订阅信息保持
  • 遗嘱消息设置
  • QoS 1/2 消息状态

💀 遗嘱消息 (Last Will)

客户端异常断开时,代理自动发布的预设消息。

配置参数:

  • Will Topic: 遗嘱主题
  • Will Message: 遗嘱消息内容
  • Will QoS: 遗嘱消息QoS
  • Will Retain: 遗嘱消息是否保留

使用场景:

  • 设备在线状态监控
  • 异常断开告警
  • 系统状态通知

❤️ 心跳机制 (Keep Alive)

客户端定期发送PINGREQ消息维持连接。

Keep Alive 参数:

  • 客户端设置的心跳间隔
  • 代理在1.5倍间隔内未收到消息则认为连接断开

心跳流程:

客户端 → PINGREQ → 代理
客户端 ← PINGRESP ← 代理

📦 消息示例

连接建立示例

CONNECT 消息:

固定头部: 0x10 (CONNECT)
可变头部: 
  Protocol Name: "MQTT" (00 04 4D 51 54 54)
  Protocol Level: 4 (0x04)
  Connect Flags: 0xC2 (11000010 - Clean Session, Will Flag, Will QoS=1)
  Keep Alive: 60秒 (00 3C)

有效载荷:
  Client ID: "device001" (00 09 64 65 76 69 63 65 30 30 31)
  Will Topic: "devices/device001/status" 
  Will Message: "offline"

CONNACK 响应:

固定头部: 0x20 (CONNACK)
可变头部: 0x00 0x00 (连接成功)

发布消息示例

QoS 0 发布:

1
2
3
4
固定头部: 0x30 (PUBLISH, QoS=0)
可变头部: 
  Topic: "sensors/temp" (00 0D 73 65 6E 73 6F 72 73 2F 74 65 6D 70)
有效载荷: "25.5"

QoS 1 发布:

1
2
3
4
5
固定头部: 0x32 (PUBLISH, QoS=1)
可变头部:
  Topic: "commands/light" 
  Packet ID: 1 (00 01)
有效载荷: "on"

🔐 安全机制

身份认证

  • 用户名/密码: CONNECT消息中携带
  • 客户端证书: TLS客户端认证
  • Token认证: 自定义令牌机制

传输安全

  • TLS/SSL加密: 端到端加密
  • VPN隧道: 网络层安全
  • 代理认证: 服务器身份验证

访问控制

  • 主题权限: 发布/订阅权限控制
  • 客户端白名单: IP地址过滤
  • 速率限制: 防止DDoS攻击

💡 实际应用案例

场景: 家庭自动化系统

  • 设备: 智能灯、传感器、控制器
  • 主题示例:
  • home/livingroom/light/switch
  • home/bedroom/temperature
  • home/security/motion
  • QoS: QoS 1用于控制命令,QoS 0用于传感器数据

场景: 工厂设备监控

  • 设备: PLC、传感器、执行器
  • 主题示例:
  • factory/line1/machine1/status
  • factory/line1/temperature
  • factory/alerts/overheat
  • QoS: QoS 2用于关键控制,QoS 1用于状态数据

场景: 车辆远程监控

  • 设备: 车载终端、云平台
  • 主题示例:
  • vehicles/car001/gps
  • vehicles/car001/diagnostics
  • commands/car001/update
  • QoS: QoS 1用于实时数据,QoS 2用于固件更新

🔧 开发工具推荐

测试工具

  • MQTT.fx: 跨平台MQTT客户端
  • MQTT Explorer: 可视化MQTT客户端
  • mosquitto_pub/sub: 命令行工具
  • Wireshark: 协议分析工具

开发库推荐

Python:

pip install paho-mqtt

JavaScript/Node.js:

npm install mqtt

Java:

1
2
3
4
<dependency>
    <groupId>org.eclipse.paho</groupId>
    <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
</dependency>

C/C++:

  • Paho MQTT C Client
  • Mosquitto Library

Go:

go get github.com/eclipse/paho.mqtt.golang

🚀 性能优化建议

客户端优化

  • 合理设置Keep Alive间隔
  • 使用持久会话减少重连开销
  • 批量发布消息减少网络往返
  • 选择合适的QoS等级

主题设计

  • 避免过深的主题层级
  • 合理使用通配符订阅
  • 主题名称尽量简短
  • 遵循一致的命名规范

网络优化

  • 使用MQTT over WebSocket适应防火墙限制
  • 配置合理的消息大小限制
  • 启用消息压缩(如果支持)
  • 使用MQTT-SN在低功耗网络

温馨提示

MQTT 协议设计简洁但功能强大,建议从简单的发布/订阅模式开始学习,逐步掌握高级特性如QoS、持久会话等。