MQTT 用户属性(User Properties)完整指南
一、是什么
User Properties(用户属性)是 MQTT 5.0 引入的一个特性。你可以把它理解成给消息贴的“便利贴”——上面写着一些自定义的键值对,用来携带额外的说明信息。
它和 Payload 是两回事:
- Payload 是消息的“正文”,也就是你真正要传的业务数据。
- User Properties 是消息的“备注”,用来携带描述这条消息的元数据。
举个例子:你给朋友寄一个包裹,包裹本身是 Payload,包裹上贴的“寄件人:张三”、“物品:衣服”、“易碎品”标签,就是 User Properties。
二、为什么需要它
在 MQTT 3.1.1 里,消息只能带 Topic 和 Payload,想传额外信息只能塞进 Payload 里。但这样会让 Payload 变得臃肿,解析也麻烦。
MQTT 5.0 引入 User Properties 后,你可以把业务数据和元数据分开:
| 内容 | 放哪里 |
|---|---|
开锁指令 {"action":"unlock"}
|
Payload |
| 谁发起的、从哪个渠道、追踪 ID | User Properties |
这样 Payload 保持干净,元数据单独传递,接收方按需读取。
三、能用在哪些报文里
User Properties 几乎可以出现在所有 MQTT 5.0 报文中:
| 报文 | 用途举例 |
|---|---|
| CONNECT | 携带设备型号、固件版本等 |
| CONNACK | 服务端返回自定义信息 |
| PUBLISH | 给消息附加业务标签 |
| PUBACK / PUBREC | 确认报文里带附加信息 |
| SUBSCRIBE / SUBACK | 订阅时携带自定义参数 |
| DISCONNECT | 断开时说明原因 |
四、和 Payload 的区别
| 对比项 | Payload | User Properties |
|---|---|---|
| 作用 | 承载业务数据 | 携带元数据、标签 |
| 格式 | 任意(JSON、二进制等) | 键值对字符串 |
| 谁解析 | 业务代码解析 | Broker 和客户端都可以读取 |
| 典型用途 | 开锁指令、状态上报 | 设备型号、消息来源、追踪 ID |
五、实际用法举例
比如你发一条开锁指令,Payload 是开锁的业务数据,User Properties 可以带上:
| 键 | 值 | 说明 |
|---|---|---|
| source | web | 从 Web 端发起的 |
| operator | user-123 | 操作人 ID |
| trace-id | abc-456 | 追踪 ID,方便排查问题 |
这样消息本身是开锁指令,但接收方还能从 User Properties 里知道是谁发起的、从哪个渠道来的,方便审计和排查。
六、代码示例(HiveMQ Client)
发送时设置:
client.publishWith()
.topic("cmd/ABDCD")
.payload("{\"action\":\"unlock\"}".getBytes())
.userProperties()
.add("source", "web")
.add("trace-id", "abc-456")
.applyUserProperties()
.send();
接收时读取:
@MqttSubscribe(topic = "cmd/+", qos = MqttQos.AT_LEAST_ONCE)
public void onCommand(Mqtt5Publish publish) {
List<Mqtt5UserProperty> props = publish.getUserProperties().asList();
for (Mqtt5UserProperty prop : props) {
System.out.println(prop.getName() + " = " + prop.getValue());
}
}
七、注意事项
- User Properties 是 MQTT 5.0 独有的,MQTT 3.1.1 不支持。如果你用的是 3.1.1 客户端,这条机制用不了。
- 多个同名的 key 是允许的,接收方需要自己处理(比如把它们当列表读取)。
- Broker 一般会原样透传,不会修改内容。
- 它适合携带少量元数据,不要用它来传大量业务数据,那应该放 Payload。
- User Properties 会增加报文体积,如果元数据很多,要留意 Maximum Packet Size 的限制。
八、一句话总结
User Properties 是 MQTT 5.0 的自定义键值对属性,可以附加在几乎所有报文上,用来携带业务元数据。它和 Payload 分工明确:Payload 传业务数据,User Properties 传标签和元信息。3.1.1 不支持这个特性。