技术参考
PSSP v1 协议
PSSP 通过基于主题的发布/订阅连接传输不透明字节负载。应用客户端决定负载的含义和持久化方式;Broker 只负责认证、授权、缓存和分发数据。
端点与 QoS
| 流量 | 端口 | 传输 | 用途 |
|---|---|---|---|
| QoS 1 | 6688 | TCP;生产环境使用 TLS 1.3 | 控制记录和需要 Broker 接收确认、确认应答、扇出及重放的数据。 |
| QoS 0 | 6688 | UDP | 在将 UDP 端点与有效 TCP 会话关联后,用于尽力而为的心跳或可容忍丢失的数据。 |
TCP 和 UDP 使用相同的数字端口,但使用独立套接字。生产环境中两者均通过已认证会话工作;UDP 使用 Broker 提供的临时令牌进行关联。
记录封装
每条 PSSP 记录由固定头部、UTF-8 JSON 控制头部和不透明字节负载组成。数字长度采用大端序。TCP 接收端必须缓存分片,直到收到完整记录。
0..1 magic:TCP 为 "PS",UDP 为 "PU"
2 协议版本:1
3 记录类型
4 标志:位 0 = AES-256-GCM 加密
5..6 JSON 头长度,无符号 16 位(默认最大 1,024)
7..10 不透明负载长度,无符号 32 位(默认最大 65,536)
11.. UTF-8 JSON 头
不透明负载字节
GCM 标签:仅加密时存在,16 字节
已认证元数据
对于加密记录,固定头和 JSON 头都是 AES-GCM 的附加认证数据。因此无法在不被检测到的情况下修改 JSON 头。
| 加密字段 | 规则 |
|---|---|
seq | 每个加密头中都必须存在的正整数。TCP 仅接受严格递增的值。UDP 维护 64 序号的重放窗口,允许正常的数据报重排序,同时拒绝重复和过旧的数据包。 |
| 会话密钥 | 每个已认证生产连接都有新的 32 字节 AES 密钥。它仅存在于 RAM 中,在连接结束时删除。 |
会话生命周期
- 连接。在端口 6688 上建立 TCP。仅在配置启用 TLS 时先协商 TLS 1.3。
- 协商。发送
HELLO;接收HELLO_ACK,其中包含协议限制、连接 ID 以及 TLS/加密策略。 - 建立保护。关闭 TLS 且启用 PSSP AES 时,验证
HELLO_ACK中固定的 Broker X25519 公钥,再发送KEY_REQUEST。双方通过 X25519 + HKDF 派生新的 AES 密钥,绝不发送对称密钥。使用 TLS + AES 时,先认证,KEY再在 TLS 内提供新的 AES 密钥。 - 认证。使用
clientId、username和password发送AUTH。仅 AES 模式会加密此记录。同一个有效客户端 ID 可保持多个并发会话。 - 使用 PSSP。订阅、发布 QoS 1 TCP 数据,并可选地绑定用于 QoS 0 的 UDP。生产环境中,密钥建立后的记录使用 AES-GCM。
- 关闭或重连。Broker 删除该连接的密钥和 UDP 关联。订阅者可用相同订阅者标识重连,并在保留数据仍可用时请求
resume。
记录类型
| 记录 | 方向 | 用途 |
|---|---|---|
HELLO / HELLO_ACK | 客户端 ↔ Broker | 版本和策略协商。 |
AUTH / AUTH_OK / AUTH_ERROR | 客户端 ↔ Broker | 凭据登录和每连接身份。 |
KEY_REQUEST / KEY | 客户端 ↔ Broker | TLS 模式在 TLS 内建立 AES。仅 AES 模式使用固定 Broker X25519 密钥 + HKDF;KEY 不携带对称密钥。 |
PING / PONG | 双方 | TCP 或 UDP 存活测试。 |
SUBSCRIBE / SUBACK | 客户端 ↔ Broker | 创建主题过滤器订阅,并以 latest、earliest 或 resume 作为起始位置。 |
UNSUBSCRIBE / UNSUBACK | 客户端 ↔ Broker | 结束一个订阅。 |
PUBLISH / PUBACK | 客户端 ↔ Broker | QoS 1 Broker 接收确认和重复重试检测。 |
MESSAGE / MSGACK | Broker ↔ 客户端 | 订阅者投递,以及应用交接后的确认。 |
GAP | Broker → 客户端 | 表示请求的数据已从有限主题内存中淘汰。 |
UDP_BIND / UDP_BIND_ACK | 客户端 ↔ Broker | 将 UDP 源端点关联到当前 TCP 会话。 |
CLOSE | 客户端 → Broker | 正常会话关闭请求。 |
主题、过滤器与授权
具体发布主题
以斜杠分隔的路径,最大 256 字节。不能包含 + 或 #、空路径元素、点路径段或控制字符。
devices/a1/audio/chunks
control/room-7/start订阅过滤器
+ 匹配一个路径段。最后一个 # 匹配所有剩余路径段。
devices/+/audio/#
control/#Broker 对每个请求评估已认证凭据的发布和订阅 ACL 过滤器。除非有明确的允许规则匹配,否则拒绝访问。
QoS、缓存与恢复
QoS 1 — TCP
- 发布者为每条可重试消息提供
publisherSessionId和单调递增的publisherSequence。 - Broker 检查身份、ACL 和限制;重复的发布者标识不会创建第二个缓存条目。
- Broker 将不透明数据加入主题的有界环形缓存,返回
PUBACK,并向匹配订阅扇出MESSAGE记录。 - 订阅者仅在自己的应用完成持久化交接后发送
MSGACK。之后可使用相同订阅者标识重连并请求resume。
QoS 0 — UDP
UDP 是尽力而为的。它没有 PUBACK、订阅者确认、重试、缓存或重放。将其用于心跳和应用可以安全丢失的数据。生产环境 UDP 使用 AES-GCM 防重放保护。
有限保留
每个主题环都有字节数、消息数和保留时间限制。如果 Broker 无法重放已被淘汰的请求序号,它将发送 GAP { earliestSequence, latestSequence }。若应用需要这些数据,必须从自己的归档中恢复。
安全模式
| 模式 | 必需标志 | 记录保护 | 适用位置 |
|---|---|---|---|
| TLS + AES | tls.enabled = trueencryption.enabled = true | TLS 1.3,随后为每会话 AES-256-GCM PSSP 记录。 | 生产网络。 |
| 仅 AES | tls.enabled = falseencryption.enabled = true固定 Broker X25519 公钥 | 临时 X25519 + HKDF 在加密认证前派生新 AES 密钥。对称密钥不经过 TCP。 | 无证书但可安全预置客户端公钥固定值的部署。 |
| 明文 | tls.enabled = falseencryption.enabled = falseallow_insecure_tcp_udp = true | 无 TLS 或 AES。短期、仅内存的 UDP 令牌仍将 UDP 绑定到已认证 TCP 会话。 | 仅可信/私有网络。 |