【从零搭建物联网智能充电桩系统】3、MQTT 客户端:设备接入云端的第一道关口

设备接入云端,靠的是 MQTT。本文讲解本项目中最核心的 MQTT 客户端模块:如何订阅设备上报、如何解析二进制报文、如何通过 Spring Integration 与 EMQX 建立连接,以及下行指令如何转发给设备。


一、模块定位

charge-mqtt-client设备接入的核心模块,全项目实现最完整(14 个 Java 文件,成熟度 ★★★★☆)。职责:

  • 上行:订阅 EMQX 的 charge/stat,接收设备二进制报文 → 解析 → 投 RabbitMQ
  • 下行:消费 RabbitMQ 的下行指令 → MQTT publish 给设备

端口:HTTP 8080 | MQTT over WebSocket: ws://emqx:8083


二、模块结构(14 个类)

复制代码
charge-mqtt-client/src/main/java/com/yeseesion/SmartChargeStation/mqtt/client/
├── MqttApplication.java            启动类
├── api/SendApi.java                发送/模拟 REST 接口(/mqtt/send、/mqtt/simulate)
├── conf/MqttProps.java             @ConfigurationProperties(prefix="mqtt") 配置映射
├── factory/
│   ├── FactoryBuilder.java         MqttPahoClientFactory 构建
│   ├── InBoundMessageRev.java      ★★核心:入站消息分发(471 行,全项目最大类)
│   ├── InBoundSubscribe.java       入站适配器/订阅配置
│   └── OutBoundSend.java           出站 Handler 配置
├── model/MqttConstants.java        通道常量 OUT_CHANNEL="out" / In_CHANNEL="in"
├── mq/
│   ├── ChargeCmdConsumer.java      消费下行指令 → MQTT
│   ├── ChargeStatConsumers.java    三路 Fanout 消费者(手动 ACK)
│   ├── ChargeStatProducer.java     Fanout 广播生产者
│   └── RabbitConfig.java           Fanout 交换机 + 3 队列 + TTL
├── service/MqttService.java        @MessagingGateway 网关接口
└── utils/TransformerUtils.java     objectToHex / hexStringToByteArray / bytesToHex

三、上行链路核心:InBoundMessageRev(471 行)

按 Topic 分发逻辑

Topic 处理
charge/stat hex → ChargeStatData.fromHexString() 解析 24 字节帧 → buildStatJson() → 投 Fanout
charge/stat/json 调试通道,直接收 JSON(跳过二进制解析)
charge/cmd 指令回环/日志

三个 HTTP 回调(均带 X-Internal-Key 头)

java 复制代码
callNettyPush()   → POST http://netty:8085/netty/push      // 推小程序
cacheStatToRedis()→ SET charge:stat:{chargeRecordId} TTL 24h
callIotDBSave()   → POST http://iotdb-service:8087/iotdb/charge/stat // 写时序库

代码 172-174 行有一段被注释掉的旧逻辑------原先收到 MQTT 后同步串行调用三个下游,重构为 RabbitMQ Fanout 后异步解耦,但旧代码未删除。


四、Spring Integration MQTT 集成(常见疑问)

关键概念

概念 本项目用法
MqttPahoClientFactory FactoryBuilder 构建,配置 broker 地址/账号/密码
MqttPahoMessageDrivenChannelAdapter 入站适配器(InBoundSubscribe),订阅 charge/stat 等
MqttPahoMessageHandler 出站 handler(OutBoundSend),publish 到 charge/cmd
@MessagingGateway MqttService 接口,声明式发送消息
Channel 内部消息通道(out / in 两个常量)

为什么用 Spring Integration 而不是裸 Paho?

  • 消息收发的生命周期由 Spring 管理,与 Boot 应用集成度高
  • 通道抽象(Channel)方便后续加拦截器/过滤器/转换器
  • 断线重连由 Paho 客户端 + Spring 适配器协同处理

下行指令的格式选择:为什么不是真·二进制?(重要!)

java 复制代码
// ChargeCmdPayload 只有字段,没有 toBytes()
// 实际发送走 TransformerUtils.objectToHex():
//   整个对象 JSON 序列化 → 转 hex 字符串 → MQTT publish

字段名(start_tag 等 snake_case)也会进 payload。这是刻意为之 :下行指令由小程序发起 ,用 JSON 序列化转 hex,小程序端和抓包工具都能直接看到请求参数 (目标桩 ID、充电时长等),调试体验远优于二进制帧。上行(设备→云端)走真·二进制是设备端省流量,下行走 JSON 是前端要可读------同一个项目里按方向选协议,这正是"按场景做取舍"的体现。

注意:若未来设备端指令下发频率变高或需严格省流,可再评估是否统一为二进制------当前下行频率低(用户手动点击),JSON 方案是合理的。


五、消息可靠性设计

层级 措施
设备→EMQX MQTT QoS 1(至少一次)
EMQX→MQTT客户端 订阅 QoS 1
MQTT客户端→下游 RabbitMQ 手动 ACK + 失败重入队(当前无重试上限,见下面缺陷)
RabbitMQ 队列 持久化队列(重启不丢)

已知缺陷basicNack(requeue=true) 且未配置死信队列(DLQ)→ 毒药消息无限重投(见 05 篇)。


六、常见问题与解答

  1. MQTT 的 QoS 0/1/2 有什么区别?为什么用 QoS 1 不用 2?(QoS1 至少一次、有重复;QoS2 恰好一次、开销大;充电状态可容忍重复上报)
  2. MQTT 的 retain 消息有什么用?(保留最近一条,新订阅者立即收到;本项目未用)
  3. buildStatJson() 把二进制解析结果转 JSON 的字段有哪些?(chargingTime/chargedEnergy/currentPower/currentCost/chargingProgress/state;注意 chargeRecordId 是 URL 参数,不在 JSON 内;state 对应"充电中/已完成"等状态枚举)
  4. 如果三个下游全部宕机,MQTT 客户端会发生什么?(RabbitMQ 消息堆积,队列 TTL 到期丢弃;MQTT 客户端本身不阻塞)
  5. Spring Integration 的 Channel 和 MQ 的 Queue 是一回事吗?(不是:Channel 是应用内消息管道,Queue 是跨应用的消息存储)

小结

MQTT 客户端是设备接入的咽喉:上行把二进制报文解析后交给 RabbitMQ 分发,下行把指令发布到 MQTT。它本身不直接连数据库,靠消息中间件与下游解耦。下一篇 【从零搭建物联网智能充电桩系统】4、Netty WebSocket 服务 讲解与小程序保持长连接的 Netty 服务端。

相关推荐
Hotchip_MEMS1 小时前
传统咪头与MEMS硅麦:雾化器气流传感方案对比
人工智能·笔记·物联网·电脑·制造
飞睿科技2 小时前
从一颗雷达芯片到一台生命体征仪:飞睿 UWB 雷达的“一芯两用”
嵌入式硬件·物联网·uwb
AISenz3 小时前
基于 AIMesh™ 的储气库高频采集与业务控制方案
物联网·信息与通信·工业物联网·物联网协议
深圳光特通信豆子3 小时前
1×9光模块DDM数字诊断监控技术手册
网络·物联网
AISenz3 小时前
基于 AIMesh™ 确定性工业无线的 AI 数据中心温控与液冷监测方案
物联网·信息与通信·工业物联网·物联网协议
Quanqiucard4 小时前
监控用物联网卡如何优化管理,降低安防项目通信成本
网络·物联网
重拳出击gogogo5 小时前
找靠谱互联网公司,我踩过的坑你知道吗?
物联网
t13970187 小时前
太阳能板与电池的电压匹配:别用开路电压 Voc,要用 Vmp
嵌入式硬件·物联网·硬件设计·电源管理·太阳能供电
大帅点兵9 小时前
车载 TBOX 大数据采集方案
大数据·物联网
MuMuMu12239 小时前
越华环保集团碳惠小屋|预制舱+物联网碳计量系统设计与工程落地要点
物联网