设备身份与 MQTT 会话局部实验(U88)
公开入口,仓库根目录,JDK 21 / Maven 3.9 / Python 3;不依赖 MySQL、Redis 或任何外部服务:
python3 labs/iot-device/run.py入口记录 JDK/Maven、执行 clean test、核对两份 Surefire 计数(合计 15)、解析依赖版本、校验 15 条 U88 观察行,写入 evidence/u88-2026-10-27.json。每个测试在 127.0.0.1 的随机端口启动一个真实的嵌入式 HiveMQ Community Edition 2026.5 broker(真实 Netty TCP 监听器、独立临时数据目录、file 持久化),测试结束 stop+close 并删除临时目录;入口创建的进程组由 runner 回收。
教材:设备身份与 MQTT 会话。通用投递语义见MQ 生产存储消费可靠性,业务幂等见重复消费、幂等与顺序消息。
公开工程:POM、runner、broker 装配、设备模拟器、设备身份/ACL 扩展、原始 MQTT 探针、身份测试、会话测试、broker 配置、运行证据。
| 测试类 | 真实运行入口 | 实际观察 |
|---|---|---|
DeviceIdentityTest(6) | 嵌入式 HiveMQ CE + 真实 TCP 客户端 | 正确凭证 SUCCESS;错误密码/匿名 CONNACK 0x87;无扩展时匿名可连(嵌入式默认放行);他人主题 SUBACK 0x87;越权 QoS1 发布 PUBACK 0x87 后 DISCONNECT;突然关闭 socket 触发遗嘱,优雅断开不触发 |
MqttSessionTest(9) | 嵌入式 HiveMQ CE + HiveMQ Client / 原始报文探针 | cleanStart=false 恢复会话并补发 3 条离线 QoS1;cleanStart=true 丢弃旧订阅;QoS0 离线丢失、QoS1 保留;QoS2 完整握手应用只收一次;未确认 QoS1 重投 DUP=1;投递 QoS 取 min;同 clientId 接管;保留消息投递/清除/跨正常重启 |
15 个测试都通过真实 socket 与真实 broker 观察行为:没有 listener mock,没有断言内部字段,没有用 stub 冒充 broker。身份与 ACL 走 broker 官方扩展点(Extension SDK 4.52.0 的 SecurityRegistry/SimpleAuthenticator/TopicPermission),是真实扩展装配而非测试桩。
本机环境(一次运行的实际值)
BellSoft Liberica JDK 21.0.11+11-LTS、Maven 3.9.9、macOS 27.2 arm64;HiveMQ Community Edition 2026.5(嵌入式)、HiveMQ Extension SDK 4.52.0、HiveMQ MQTT Client 1.4.1、Netty 4.1.134.Final、JUnit Jupiter 6.0.3。实际解析版本、退出码、观察行与文件 SHA-256 见入口生成的 evidence/u88-*.json。
边界
- 无 TLS/mTLS、MQTT 5 增强认证(AUTH 报文)、WebSocket 监听器、外部凭据源(数据库/OAuth)。
- keep-alive 超时触发遗嘱、takeover 时旧连接遗嘱时序、MQTT 3.1.1 行为差异只给规范/源码依据,未实跑。
- broker 重启是正常
stop+close后重开,不是 kill -9、断电或文件系统损坏恢复。 - 保留消息跨重启验证限于同机正常停机;不能推广为崩溃一致性。
- 无 broker 集群/桥接/共享订阅跨节点,无生产容量与队列溢出压测。
- 身份模型是教学实现(用户名/密码由设备 id 派生),不是生产设备证书体系或动态注册流程。
- 只使用合成设备 id、127.0.0.1 随机端口与临时目录;不写用户数据,不触碰本机其他服务。
已知未运行
TLS/mTLS 与客户端证书、增强认证、WebSocket、外部凭据源、keep-alive 超时路径、跨 broker 集群与桥接、共享订阅跨节点、队列溢出与容量压测、kill -9/断电恢复均未在本实验运行;对应结论在正文与账本中按源码/规范推演或明确未运行标注。