首页/目录/全部文章

全部文章

八个专题的源码、算法与协议笔记都在这里。

笔记列表

QoS 与消息投递

QoS 与消息投递

MQTT 提供三种 Quality of Service:在开销与可靠性之间折中
规范表述(5.0):At most once / At least once / Exactly once


1. 三种 QoS

QoS 名称 保证 可能结果 典型场景
0 At most once 尽力投递 可能丢失 高频传感器、可丢一帧
1 At least once 必达 可能重复 命令、告警、多数业务
2 Exactly once 仅一次 握手最重 计费、关键状态机(慎用)

OASIS 说明摘要:QoS0 可丢;QoS1 保证到达但可重复;QoS2 保证恰好一次。


2. 握手过程

QoS 0

1
Sender ──PUBLISH──▶ Receiver

无确认。最快、最省。

QoS 1

1
2
Sender ──PUBLISH (Packet ID)──▶ Receiver
Sender ◀─PUBACK─────────────── Receiver

超时重传 PUBLISH → 接收方可能收到重复 → 应用需幂等

QoS 2

1
2
3
4
Sender ──PUBLISH──▶ Receiver
Sender ◀─PUBREC──── Receiver
Sender ──PUBREL───▶ Receiver
Sender ◀─PUBCOMP─── Receiver

四步握手,存储与往返最多,延迟与复杂度最高。


3. “端到端”到底保证到哪?

重要澄清:

  • QoS 是 MQTT 协议端(Client↔Broker 或转发路径上的协议跳) 的保证
  • 发布端到订阅端通常是 两段:Publisher→Broker、Broker→Subscriber
  • 最终有效 QoS 受两段中的约束影响(实现会取合适等级)

因此:

  • 选 QoS2 不等于业务绝对“全局恰好一次”
  • 分布式系统仍常需业务幂等键 / 去重

4. 如何选择(实用)

场景 建议
关节状态 50Hz 遥测 QoS0 或 QoS1 + 可接受重复
模式切换 / 急停命令 QoS1 + 幂等命令 ID
计费/库存扣减 QoS1/2 + 强幂等(别只靠 QoS2)
弱网手机 QoS1 + 会话恢复,观察重传风暴

经验:大多数业务用 QoS1 + 幂等 比全面 QoS2 更稳。


5. 重复与乱序

  • QoS1 重传 ⇒ 重复交付
  • 多订阅、桥接、集群 ⇒ 可能看到乱序(相对单一流)
  • Payload 应带:seq / timestamp / message_id

6. 流控相关(MQTT 5)

MQTT 5 引入更明确的流控属性,例如:

  • Receive Maximum
  • Maximum Packet Size
  • Topic Alias Maximum

避免发送方打爆接收方;详见 04-MQTT5新特性.md


7. 与 ROS 2 DDS QoS 对照(帮助选型)

MQTT 近似 DDS 直觉
QoS0 BEST_EFFORT
QoS1 RELIABLE + 可能重复
Retain 有点像 TRANSIENT_LOCAL 的“晚加入拿到最后状态”
Session 不同于 DDS History;是协议会话状态

二者不是一一映射;桥接时要显式设计丢失/重复策略。

下一篇:04-MQTT5新特性.md

MQTT 5.0 新特性

MQTT 5.0 新特性

MQTT 5.0 = 在保留核心 Pub/Sub 的前提下,大幅增强可诊断性、可扩展性、大规模与互操作
正式标准:https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html
批准日期:2019-03-07

规范自述的功能目标包括:增强错误报告、共享订阅、消息过期、主题别名、用户属性、增强认证、流控等。


1. 为什么需要 5.0

3.1.1 的痛点:

  • 失败时常只看到很粗的返回码
  • 大消息/慢消费者缺少标准化流控
  • 请求/响应模式要自己约定
  • 元数据只能塞进 Payload

5.0 用 Reason Code + Properties 系统化解决。


2. Reason Code

几乎所有确认/断开报文可携带 Reason Code:

  • 成功 / 各类失败原因更细
  • DISCONNECT 可说明“为什么踢你”
  • SUBACK 可按订阅项返回结果

排障价值极高:少猜、多读码。


3. Properties(属性)

控制报文可带属性列表,重要者包括:

属性 用途
Session Expiry Interval 会话保留多久
Message Expiry Interval 消息过期
Content Type 载荷类型提示
Response Topic / Correlation Data 请求-响应
Subscription Identifier 订阅标识,回调分流
Topic Alias 用短别名降低重复主题开销
User Property 任意键值元数据(UTF-8)
Receive Maximum 未确认 QoS1/2 上限
Maximum Packet Size 包大小上限
Server Keep Alive 服务端可覆盖 Keep Alive
Authentication Method/Data 增强认证

4. 共享订阅

$share/{ShareName}/{TopicFilter}
组内负载均衡,见 01-主题与发布订阅模型.md


5. 请求 / 响应模式

标准化字段:

  • Response Topic:响应发到哪里
  • Correlation Data:把响应对回请求

不必再靠私有约定“reply_to”塞进 JSON(当然仍可并存)。


6. 主题别名(Topic Alias)

对高频、长 Topic:

  1. 首次 PUBLISH 带完整 Topic + Alias
  2. 后续只用 Alias

显著降低带宽(对受限网络友好)。


7. 增强认证(AUTH)

除用户名密码外,支持多步认证交换(SASL 风格思路):

  • CONNECT 声明 Authentication Method
  • 后续 AUTH 报文往返

适合企业身份源、令牌刷新、更强质询应答。


8. 负反馈与“服务端能力”

CONNACK 可告知:

  • 服务器支持的最大 QoS、最大包长、是否保留可用、共享订阅是否可用等

Client 应按 CONNACK 调整行为,而不是假设所有 Broker 能力相同。


9. 迁移建议

策略 说明
双栈 Broker Mosquitto/EMQX/HiveMQ CE 等多同时支持 3.1.1 与 5.0
新服务优先 5.0 直接受益于 Reason Code / 属性
旧设备保留 3.1.1 通过 Broker 互通(注意特性降级)
桥接注意 5.0 属性跨桥可能丢失,需测

下一篇:05-安全与认证.md

安全与认证

安全与认证

MQTT 规范本身把安全留给传输层与实现;工程上必须主动设计
底线:生产环境不要裸奔 1883 对公网


1. 传输层加密

端口(惯例) 含义
1883 明文 MQTT
8883 MQTT over TLS
80/443 常用于 WebSocket / WSS(以实现为准)

实践:

  • 启用 TLS 1.2+
  • 校验证书主机名
  • 需要时做双向 TLS(mTLS):设备持客户端证书

2. 应用层身份

常见方式:

  1. Username / Password(CONNECT)
  2. 客户端证书(TLS)
  3. Token(密码字段塞 JWT,或 MQTT5 增强认证)
  4. MQTT 5 AUTH 多步认证

原则:身份与设备身份生命周期(签发、轮换、吊销)要有流程。


3. 授权(ACL)

认证解决“你是谁”;授权解决“你能碰哪些 Topic”。

典型 ACL:

1
2
3
4
用户 agv07:
可发布:siteA/agv07/cmd/#
可订阅:siteA/agv07/state/#
禁止: $SYS/# 、别人的命名空间

Broker 侧(Mosquitto acl_file、EMQX ACL 规则、HiveMQ 扩展等)配置。
最小权限:设备不能订阅全网 #


4. 载荷安全

TLS 保护通道,不自动保证:

  • 应用层完整业务授权
  • 端到端对 Broker 不可见的保密(若需要,对 Payload 再加密)
  • 防重放(加时间戳/nonce + 服务端校验)

5. 网络安全分层

1
2
3
4
5
设备 --TLS--> Broker(DMZ) --TLS/内网--> 后端服务

├─ ACL
├─ 速率限制
└─ 审计日志

机器人场景补充:

  • 车载/产线 MQTT 与办公室 IT 网隔离
  • 仅桥接必要 Topic 到云
  • 急停等安全功能不要只靠 MQTT(需独立安全通道)

6. 常见误区

误区 正确做法
内网就不用 TLS 内网也会被横移攻击;至少要认证+ACL
强密码就够 还需 Topic 级授权与证书轮换
Retain 命令 危险:后来者可能执行旧命令;命令慎用 Retain
共享账号 审计困难;一人一证/一设备一身份

下一篇:06-开源Broker与客户端对比.md

开源 Broker 与客户端对比

开源 Broker 与客户端对比

本地克隆见:../开源项目/
许可证与集群能力请以各仓库当前 LICENSE / 文档为准(商业版规则会变)


1. Broker 总览

项目 语言 许可(常见) 特点 本地目录
Eclipse Mosquitto C EPL-2.0 / EDL 轻量、易部署、桥接成熟 mosquitto/
EMQX Erlang/OTP 注意版本许可变化(近年 BSL 等) 高并发、规则引擎、云边功能全 emqx/
HiveMQ CE Java Apache-2.0 规范实现严谨、扩展生态 hivemq-community-edition/
NanoMQ C 见仓库 边缘/嵌入式友好、轻量 nanomq/
VerneMQ Erlang Apache-2.0(发行策略另查) 集群向 (未默认克隆)

选型直觉:

  • 单机/产线小规模/学习:Mosquitto
  • 边缘网关资源紧:NanoMQ / Mosquitto
  • 大规模接入、规则流转:评估 EMQX(看清许可)
  • 强调 MQTT5 正确性与扩展:HiveMQ CE

2. 客户端库

项目 语言 本地目录 说明
Eclipse Paho Python Python paho.mqtt.python/ 脚本、测试、ROS 辅助常用
Eclipse Paho C C paho.mqtt.c/ 嵌入式/高性能 C 客户端
MQTT.js JavaScript MQTT.js/ Node / 前端 WebSocket
HiveMQ MQTT Client Java (未默认克隆) 强 MQTT5、响应式 API
Paho 其它语言 Java/Go/… 按需另克隆 https://eclipse.dev/paho/

3. ROS 2 相关

项目 本地目录 说明
mqtt_client(ika-rwth-aachen) ros2_mqtt_client/ ROS 2 ↔ MQTT 桥接常用之一

详见 07-ROS2与MQTT集成.md


4. 功能维度对比(工程关注点)

维度 关注问题
MQTT 版本 是否完整 5.0
持久化 重启后 Retain / 会话?
桥接 多 Broker 互联?
集群 单机够用还是要水平扩展?
认证插件 证书 / JWT / HTTP 钩子?
可观测 指标、慢订阅、追踪
资源占用 能否跑进网关/工控机

5. 快速体验(Mosquitto 示例)

1
2
3
4
5
6
# 安装后(系统包或自编译)
mosquitto -c mosquitto.conf

# 另一终端
mosquitto_sub -h localhost -t 'test/#' -v
mosquitto_pub -h localhost -t 'test/hello' -m 'world' -q 1

下一篇:07-ROS2与MQTT集成.md

ROS 2 与 MQTT 集成

ROS 2 与 MQTT 集成

目标:让机器人内部的 ROS 2 话题与外部 MQTT 世界互通
本地示例工程:../开源项目/ros2_mqtt_client(ika-rwth-aachen/mqtt_client)


1. 为什么要桥接

典型中间件
机器人内部实时控制 / 感知 ROS 2(DDS)、EtherCAT、CANopen
厂级 SCADA / 云 / 移动 App MQTT、HTTP、Kafka 等

MQTT 擅长:跨网络、跨语言、跨组织的遥测与命令
不替代 DDS 做车内硬实时。

1
2
3
4
5
6
7
[ROS 2 Nodes / DDS]

mqtt_client / 自定义桥

MQTT Broker

云平台 / 手机 / 其它产线系统

2. mqtt_client 能做什么(概念)

(以仓库 README 为准)

  • 将 ROS 话题桥到 MQTT Topic(及反向)
  • 配置 QoS、话题映射、序列化方式
  • 作为 ROS 2 包接入 launch

本地路径:../开源项目/ros2_mqtt_client


3. 集成设计要点

3.1 话题映射

明确约定,例如:

1
2
ROS:  /arm/joint_states
MQTT: siteA/robot1/arm/joint_states

避免直接把 ROS 命名空间无前缀暴露到公网 Broker。

3.2 序列化

方案 说明
JSON 易读、易与 Web 对接;体积大
CDR / 自定义二进制 紧凑;对端要有同解码
Protobuf 跨语言契约清晰

桥接处是契约边界:加版本字段,避免静默不兼容。

3.3 QoS 与频率

  • 高频率 TF / 点云:不要无脑桥到 MQTT
  • 状态摘要、告警、任务指令:适合 MQTT
  • 降采样、节流、关键字段抽取

3.4 安全

  • 独立 MQTT 账号与 ACL
  • TLS
  • 命令 Topic 鉴权 + 应用层确认
  • 安全相关急停保持在本地实时通道

4. 推荐落地步骤

  1. 本机起 Mosquitto,用 mosquitto_pub/sub 打通
  2. 用 Paho Python 模拟云端订阅者
  3. 接入 mqtt_client,先桥一条低频率 String/JSON
  4. 再扩到状态摘要;命令通道加幂等与超时
  5. 压测:慢订阅、断网重连、Retain/LWT 行为

5. 与其它仓库文档的关系

  • DDS 细节:../../ros2doc/(若有 CycloneDDS 等笔记)
  • 实时总线:../../EtherCAT/../../CANopen/
  • MQTT 排障:08-调试与运维.md

下一篇:08-调试与运维.md

调试与运维

调试与运维

口诀:先连通,再鉴权,再订阅匹配,最后才看业务 Payload
工具:mosquitto_pub/sub、Broker 日志、Wireshark、应用 Reason Code(MQTT5)


1. 最小连通性检查

1
2
3
4
5
# 终端 A:订阅
mosquitto_sub -h 127.0.0.1 -p 1883 -t 'debug/#' -v

# 终端 B:发布
mosquitto_pub -h 127.0.0.1 -p 1883 -t 'debug/ping' -m 'pong' -q 1

TLS 示例:

1
2
mosquitto_sub -h broker.example -p 8883 \
--cafile ca.crt -t 'debug/#' -v

2. 分层排障

L0 网络

现象 检查
连不上 端口、防火墙、DNS、容器网络
TLS 握手失败 证书链、时间、SNI、TLS 版本

L1 协议会话

现象 检查
CONNACK 拒绝 用户名密码、Client ID 冲突、协议版本
频繁掉线 Keep Alive、NAT 超时、心跳
互相踢下线 重复 Client ID

L2 路由

现象 检查
发布成功但收不到 Topic 拼写、通配符、ACL 拒绝订阅
只有新订阅有数据 是否依赖 Retain;发布端是否置 Retain
共享订阅不均衡 Broker 是否支持、ShareName 是否一致

L3 应用

现象 检查
偶发重复 QoS1 重传 → 幂等
JSON 解析失败 编码、截断、最大包长
桥接延迟大 慢消费者、队列堆积、无节流

3. Broker 侧观察

  • Mosquitto:日志级别、$SYS/#(若启用)
  • EMQX / HiveMQ:Dashboard / 指标 / 慢订阅监控

关注:

  • 当前连接数
  • 每秒消息数
  • 堆叠的未确认 QoS 消息
  • ACL 拒绝计数

4. 抓包

  • Wireshark:过滤 mqtttcp.port==1883
  • TLS 场景需密钥或改在 Broker 侧打明文日志(注意隐私)

MQTT5:优先读 Reason Code 与 DISCONNECT 原因,少靠猜。


5. 运维 Checklist

  • 生产强制 TLS + ACL
  • Client ID 规范(唯一、可追溯)
  • 保留消息策略评审(命令 Topic 慎用 Retain)
  • 磁盘持久化与备份(若启用)
  • 监控告警:连接数、拒绝数、队列深度
  • 版本策略:3.1.1 / 5.0 混部测试
  • 升级演练与桥接回归

6. 本地开源项目入口

目的 目录
轻量 Broker ../开源项目/mosquitto
边缘 Broker ../开源项目/nanomq
大规模 Broker ../开源项目/emqxhivemq-community-edition
Python 客户端 ../开源项目/paho.mqtt.python
C 客户端 ../开源项目/paho.mqtt.c
JS 客户端 ../开源项目/MQTT.js
ROS 2 桥 ../开源项目/ros2_mqtt_client

下一篇:09-规范与资料索引.md

规范与资料索引

规范与资料索引

整理日期:2026-09-03
正式规范以 OASIS / mqtt.org 为准


1. 正式规范

版本 状态 链接
MQTT 5.0 OASIS Standard (2019-03-07) HTML · 规范页
MQTT 3.1.1 OASIS Standard;亦 ISO/IEC 20922 HTML
MQTT 3.1 历史 mqtt.org specifications
MQTT-SN v1.2 传感器网络变体 见 mqtt.org 规范页

总入口:https://mqtt.org/mqtt-specification/


2. 与本仓库文档映射

规范主题 中文文档
Pub/Sub 总览 0001
Control Packets / Session 02
QoS 03
MQTT 5 新特性 04
§2/§3 控制报文字节格式 1015
安全(工程) 05
实现选型 06
ROS 2 07
排障 08

3. 学习与生态


4. 版本对照速记

能力 3.1.1 5.0
基础 Pub/Sub / QoS
Reason Code / Properties
Shared Subscription ✗(有私有扩展)
Topic Alias
Request/Response 字段
AUTH 增强认证
Session Expiry 精细控制 有限

本目录文档是工程向整理,不替代 OASIS 规范正文。

MQTT 控制报文格式总览(OASIS)

MQTT 控制报文格式总览(OASIS)

依据正式标准整理(学习用中文详解,不替代原文):
MQTT Version 5.0 OASIS Standard,2019-03-07
https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html
对应规范章节:§2 MQTT Control Packet format§3 MQTT Control Packets
兼容阅读:MQTT 3.1.1 https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html

下文默认描述 MQTT 5.0;与 3.1.1 差异会单独标注。


1. 控制报文三段式结构(§2.1)

每个 MQTT Control Packet 由三部分组成:

1
2
3
4
┌──────────────────┬─────────────────────┬─────────────┐
│ Fixed Header │ Variable Header │ Payload │
│ (固定报头) │ (可变报头,可缺省) │ (载荷,可缺省)│
└──────────────────┴─────────────────────┴─────────────┘
部分 是否必须 内容
Fixed Header 必须 报文类型、标志、剩余长度
Variable Header 多数报文有 Packet Identifier、属性、主题名等
Payload 部分报文有 ClientID、Will、用户名密码、订阅列表、应用消息等

2. Fixed Header(§2.1.1)

最少 2 字节(当 Remaining Length < 128 时):

1
2
3
4
5
 Byte 1                         Byte 2…
┌────────────┬────────────────┬─────────────────────────┐
│ MQTT Type │ Flags │ Remaining Length │
│ (bit7-4) │ (bit3-0) │ (1~4 字节可变编码) │
└────────────┴────────────────┴─────────────────────────┘

2.1 报文类型(§2.1.2)

报文 方向 说明
1 CONNECT C→S 连接请求(连接后第一包必须是 CONNECT [MQTT-3.1.0-1])
2 CONNACK S→C 连接确认
3 PUBLISH 双向 发布
4 PUBACK 双向 QoS1 确认
5 PUBREC 双向 QoS2 第 1 步
6 PUBREL 双向 QoS2 第 2 步
7 PUBCOMP 双向 QoS2 第 3 步
8 SUBSCRIBE C→S 订阅
9 SUBACK S→C 订阅确认
10 UNSUBSCRIBE C→S 取消订阅
11 UNSUBACK S→C 取消确认
12 PINGREQ C→S 心跳请求
13 PINGRESP S→C 心跳响应
14 DISCONNECT 双向(5.0) 断开
15 AUTH 双向(仅 5.0 增强认证

2.2 Flags(bit3–0)

多数报文 Flags 必须为 0(规范强制位)。例外:

报文 bit3 bit2 bit1 bit0
PUBLISH DUP QoS MSB QoS LSB RETAIN
PUBREL / SUBSCRIBE / UNSUBSCRIBE 0 0 1 0

错误 Flags → 协议错误,对端应关闭网络连接(规范行为)。


3. Remaining Length(§2.1.4)

Variable Header + Payload 的字节数做 Variable Byte Integer 编码(1~4 字节):

编码字节数 可表示最大值
1 127(0x7F
2 16 383
3 2 097 151
4 268 435 455

算法要点:每字节低 7 位为数据,最高位为续传标志。


4. 基本数据类型(§1.5 / §2.2)

类型 编码
Byte 1 字节
Two Byte Integer 大端 16-bit
Four Byte Integer 大端 32-bit
Variable Byte Integer 同上 Remaining Length 算法
UTF-8 Encoded String 2 字节长度(大端)+ UTF-8 字节
Binary Data 2 字节长度 + 二进制
Properties(仅 5.0) Property Length + 属性列表

字符串不得含 U+0000;规范对部分字段还有格式约束。


5. Properties(MQTT 5,§2.2.2)

可变报头中可出现属性区:

1
2
3
4
┌──────────────────┬────────────────────────────────┐
│ Property Length │ Property1 │ Property2 │ … │
│ (Var Byte Int) │ id+value │ … │
└──────────────────┴────────────────────────────────┘

每个 Property = Identifier(1 字节) + 类型对应的 Value。
标识符示例(完整表见 15):

ID 名称 常见出现处
0x11 Session Expiry Interval CONNECT / CONNACK
0x21 Receive Maximum CONNECT / CONNACK
0x27 Maximum Packet Size CONNECT / CONNACK
0x22 Topic Alias Maximum CONNECT / CONNACK
0x23 Topic Alias PUBLISH
0x08 Response Topic PUBLISH / Will
0x09 Correlation Data PUBLISH / Will
0x26 User Property 多处
0x1F Reason String CONNACK / PUBACK / DISCONNECT…

3.1.1 无 Properties


6. Packet Identifier(§2.2.1)

  • 两字节大端整数,非零
  • QoS > 0 的 PUBLISH,以及 PUBACK/PUBREC/PUBREL/PUBCOMP、SUBSCRIBE/SUBACK、UNSUBSCRIBE/UNSUBACK 使用
  • QoS0 PUBLISH、CONNECT、CONNACK、PING、部分 DISCONNECT Packet Identifier

7. Reason Code(MQTT 5,§2.4)

确认/断开类报文可带 1 字节 Reason Code,比 3.1.1 的粗粒度返回码细得多。
0x00 通常表示成功。目录见 15


8. 文档地图(官方 §3 对照)

本库文档 覆盖 OASIS 章节
11-CONNECT与CONNACK报文格式.md §3.1~3.2
12-PUBLISH与QoS握手报文格式.md §3.3~3.7
13-SUBSCRIBE与UNSUBSCRIBE报文格式.md §3.8~3.11
14-PING-DISCONNECT-AUTH报文格式.md §3.12~3.15
15-Reason-Code与Properties目录.md §2.2.2、§2.4 及各报文 Reason

工程概念篇仍见 0004;本系列专注比特/字节级官方控制报文

下一篇:11-CONNECT与CONNACK报文格式.md

CONNECT 与 CONNACK 报文格式

CONNECT 与 CONNACK 报文格式

OASIS MQTT 5.0:§3.1 CONNECT§3.2 CONNACK
https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html
规范要求:网络连接建立后,Client 发送的第一包必须是 CONNECT [MQTT-3.1.0-1]


1. CONNECT – Connection Request(§3.1)

1.1 Fixed Header

字段
Type 1(CONNECT)
Flags 必须 0000
Remaining Length Variable Header + Payload 长度

1.2 Variable Header 顺序

1
Protocol Name → Protocol Version → Connect Flags → Keep Alive → Properties(5.0)

Protocol Name / Version

字段 MQTT 5.0 MQTT 3.1.1
Protocol Name UTF-8 字符串 MQTT 同为 MQTT(3.1 曾为 MQIsdp
Protocol Version 5 4

Connect Flags(1 字节)

1
2
3
4
5
6
 bit7      bit6       bit5        bit4 bit3   bit2        bit1         bit0
┌────────┬──────────┬───────────┬──────────┬────────────┬─────────────┬─────┐
│UserName│ Password │ Will │ Will QoS │ Will Retain│ Clean Start │ Res │
│ Flag │ Flag │ Flag │ │ │ (Clean Ses.*)│ =0 │
└────────┴──────────┴───────────┴──────────┴────────────┴─────────────┴─────┘
* 3.1.1 中 bit1 名为 Clean Session
含义
Clean Start (5.0) / Clean Session (3.1.1) 是否丢弃旧会话并新建
Will Flag 1 则 Payload 含 Will Topic/Payload(5.0 还有 Will Properties)
Will QoS / Will Retain 遗嘱消息的 QoS 与 Retain
User Name / Password Flag Payload 是否含对应用户字段
Reserved bit0 必须为 0

Keep Alive

  • Two Byte Integer,单位:
  • 表示 Client 在无其它控制报文时发送 PINGREQ 的最长间隔相关约定
  • Server 若在 1.5 × Keep Alive 内未收到 Client 控制报文,可判定连接断开并处理 Will(规范定义)

CONNECT Properties(仅 5.0,§3.1.2.11)

常见属性:

属性 作用
Session Expiry Interval 断线后会话保留秒数;0xFFFFFFFF 表示永不过期
Receive Maximum Client 未确认 QoS1/2 上限
Maximum Packet Size Client 愿接收的最大包
Topic Alias Maximum Client 支持的主题别名上限
Request Response Information 请求 Server 在 CONNACK 给 Response Information
Request Problem Information 是否希望 Reason String / User Property
User Property 自定义键值
Authentication Method / Data 增强认证

1.3 Payload 顺序(按 Flags 条件出现)

1
2
3
4
5
6
1. Client Identifier          (必须)
2. Will Properties (5.0) (Will Flag=1)
3. Will Topic (Will Flag=1)
4. Will Payload (Will Flag=1)
5. User Name (User Name Flag=1)
6. Password (Password Flag=1)

ClientID:UTF-8;Server 可分配(CONNACK Assigned Client Identifier)。空 ClientID 时规范对 Clean Start 等有额外约束。


2. CONNACK – Connect acknowledgement(§3.2)

2.1 Fixed Header

Type Flags
2 必须 0000

2.2 Variable Header

1
Connect Acknowledge Flags (1) → Reason Code (1, 5.0) / Return Code (3.1.1) → Properties(5.0)

Connect Acknowledge Flags

  • bit0:Session Present
    • 1:Server 从已有会话恢复
    • 0:新会话
  • 其余位必须为 0

Connect Reason Code(5.0)/ Return Code(3.1.1)

5.0 Reason(例) 含义
0x00 Success
0x81 Malformed Packet
0x82 Protocol Error
0x84 Unsupported Protocol Version
0x85 Client Identifier not valid
0x86 Bad User Name or Password
0x87 Not authorized
0x88 Server unavailable
0x89 Server busy
0x8A Banned
0x8C Bad authentication method
0x90 Topic Name invalid
0x95 Packet too large
0x97 Quota exceeded
0x99 Payload format invalid
0x9A Retain not supported
0x9B QoS not supported
0x9C Use another server
0x9D Server moved
0x9F Connection rate exceeded

3.1.1 Return Code 仅 0x000x05 等少数值。

CONNACK Properties(5.0)— Server 能力通告

属性 含义
Session Expiry Interval Server 使用的会话过期
Receive Maximum Server 未确认上限
Maximum QoS Server 支持的最大 QoS(0/1/2)
Retain Available 是否支持 Retain
Maximum Packet Size Server 最大包
Assigned Client Identifier 分配的 ClientID
Topic Alias Maximum Server 主题别名上限
Reason String 人类可读原因
Wildcard / Shared / Subscription Identifier Available 能力位
Server Keep Alive Server 覆盖的 Keep Alive
Response Information 响应相关信息
Server Reference 另选服务器
Authentication Method / Data 增强认证继续

2.3 Payload

CONNACK 无 Payload


3. 连接时序(报文级)

1
2
3
4
5
Client                          Server
│──────── CONNECT ─────────────▶│
│◀─────── CONNACK ──────────────│
│ (若 Reason≠0:通常关闭连接) │
│──────── PUBLISH/SUBSCRIBE … ─▶│

增强认证时,CONNECT 后可能穿插 AUTH 往返(见 14)。


4. 3.1.1 vs 5.0 差异速记

3.1.1 5.0
Protocol Level 4 5
Clean Clean Session Clean Start + Session Expiry
失败信息 粗 Return Code Reason Code + Properties
Will Topic+Payload + Will Properties(Delay 等)
能力协商 CONNACK Properties

下一篇:12-PUBLISH与QoS握手报文格式.md

PUBLISH 与 QoS 握手报文格式

PUBLISH 与 QoS 握手报文格式

OASIS MQTT 5.0:§3.3 PUBLISH§3.4 PUBACK§3.5 PUBREC§3.6 PUBREL§3.7 PUBCOMP
QoS 语义综述另见:03-QoS与消息投递.md


1. PUBLISH(§3.3)

1.1 Fixed Header

1
Type=3 | DUP | QoS1 | QoS0 | RETAIN | Remaining Length…
标志 含义
DUP 1=可能是重传的 PUBLISH(QoS>0);接收方须按 Packet ID 去重/续传逻辑处理
QoS 00=0,01=1,10=2;11 非法 → 协议错误
RETAIN 1=Server 应作为该 Topic 的保留消息存储/替换(空载荷 Retain 可删除保留消息,见规范)

1.2 Variable Header

1
Topic Name → Packet Identifier(若 QoS>0) → Properties(5.0)
字段 规则
Topic Name UTF-8;不得含通配符;可用 Topic Alias 缩短(5.0)
Packet Identifier QoS 1/2 必须;QoS 0 不得出现
Properties Payload Format、Message Expiry、Topic Alias、Response Topic、Correlation Data、User Property、Subscription Identifier、Content Type 等

1.3 Payload

  • 应用消息原始字节;长度 = Remaining Length − Variable Header 长度
  • 协议对内容不可知(JSON/Protobuf/二进制均可)

1.4 抓包心算

1
2
3
4
Fixed Header: 0x30 = PUBLISH, QoS0, no DUP, no RETAIN
Fixed Header: 0x32 = PUBLISH, QoS1
Fixed Header: 0x33 = PUBLISH, QoS1 + RETAIN
Fixed Header: 0x34 = PUBLISH, QoS2

2. QoS 0:无确认

1
Sender ──PUBLISH (QoS0)──▶ Receiver

无 Packet Identifier;可丢。


3. QoS 1:PUBACK(§3.4)

1
2
Sender ──PUBLISH (QoS1, PacketID=P, DUP?)──▶ Receiver
Sender ◀─PUBACK (PacketID=P, Reason?)───── Receiver

PUBACK 结构

部分 内容
Fixed Header Type=4,Flags=0000
Variable Header Packet Identifier;5.0 可跟 Reason Code + Properties
Payload

成功 Reason 常为 0x00 Success;亦可 0x10 No matching subscribers 等(5.0,视角色)。

超时未收到 PUBACK → Sender 以 DUP=1 重传同一 Packet ID 的 PUBLISH。


4. QoS 2:四步握手(§3.5~3.7)

1
2
3
4
Sender ──PUBLISH (QoS2, P)──▶ Receiver
Sender ◀─PUBREC (P)───────── Receiver
Sender ──PUBREL (P)─────────▶ Receiver # Flags 必须 0010
Sender ◀─PUBCOMP (P)───────── Receiver
报文 Type Flags 作用
PUBREC 5 0000 Receiver:已收到,进入第二阶段
PUBREL 6 0010 Sender:释放;可带 Reason(5.0)
PUBCOMP 7 0000 Receiver:完成

任一步超时按规范重传对应报文;状态机必须持久化未完成流(会话恢复相关)。

MQTT 5 下 PUBREC/PUBREL/PUBCOMP 均可带 Reason Code + Properties(如 Reason String)。


5. 端到端注意(规范视角)

  • QoS 保证的是 MQTT 协议跳(如 Client↔Server),不是自动的业务全局 exactly-once
  • Publisher→Server 与 Server→Subscriber 是两段独立 QoS
  • 应用层仍建议:message_id / 幂等键

6. 3.1.1 vs 5.0

3.1.1 5.0
PUBACK 等 仅 Packet ID + Reason Code + Properties
PUBLISH 元数据 无标准属性 Topic Alias、Expiry、Response Topic…
无匹配订阅者 无标准反馈 PUBACK Reason 0x10

下一篇:13-SUBSCRIBE与UNSUBSCRIBE报文格式.md