mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-07-15 11:17:52 +08:00
wiki生成
This commit is contained in:
638
docs/核心模块详解/协议实现模块/云快充协议实现/上行消息处理.md
Normal file
638
docs/核心模块详解/协议实现模块/云快充协议实现/上行消息处理.md
Normal file
@@ -0,0 +1,638 @@
|
||||
# 上行消息处理
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java)
|
||||
- [ProtocolCmd.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/annotation/ProtocolCmd.java)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java)
|
||||
- [YunKuaiChongUplinkCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongUplinkCmdExe.java)
|
||||
- [YunKuaiChongUplinkMessage.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongUplinkMessage.java)
|
||||
- [KafkaForwarder.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/forwarder/KafkaForwarder.java)
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java)
|
||||
- [YunKuaiChongV150LoginULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150LoginULCmd.java)
|
||||
- [YunKuaiChongV150StartChargeULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150StartChargeULCmd.java)
|
||||
- [YunKuaiChongV150RealTimeDataULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150RealTimeDataULCmd.java)
|
||||
- [YunKuaiChongV150TransactionRecordULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150TransactionRecordULCmd.java)
|
||||
- [YunKuaiChongProtocolConstants.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolConstants.java)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
|
||||
1. [概述](#概述)
|
||||
2. [系统架构](#系统架构)
|
||||
3. [消息处理流程](#消息处理流程)
|
||||
4. [协议命令注解机制](#协议命令注解机制)
|
||||
5. [关键上行命令详解](#关键上行命令详解)
|
||||
6. [消息转发机制](#消息转发机制)
|
||||
7. [数据持久化与状态管理](#数据持久化与状态管理)
|
||||
8. [性能优化策略](#性能优化策略)
|
||||
9. [总结](#总结)
|
||||
|
||||
## 概述
|
||||
|
||||
云快充协议上行消息处理系统是一个高度模块化的分布式消息处理框架,负责接收、解析、分发和处理来自充电桩的各种上行消息。该系统采用事件驱动架构,通过反射机制和命令路由模式实现灵活的消息处理。
|
||||
|
||||
核心特性包括:
|
||||
|
||||
- **高性能TCP监听**:基于Netty的异步I/O处理
|
||||
- **智能协议解析**:支持多种协议版本的统一处理
|
||||
- **反射命令路由**:基于注解的自动化命令分发
|
||||
- **消息转发队列**:通过Kafka实现异步消息传递
|
||||
- **状态管理**:实时更新充电桩状态和属性
|
||||
|
||||
## 系统架构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "网络层"
|
||||
TCP[TCP监听器]
|
||||
Session[TCP会话管理]
|
||||
end
|
||||
subgraph "协议处理层"
|
||||
Processor[云快充协议处理器]
|
||||
Router[命令路由器]
|
||||
Message[消息解析器]
|
||||
end
|
||||
subgraph "命令执行层"
|
||||
Heartbeat[心跳命令]
|
||||
Login[登录命令]
|
||||
Charge[充电命令]
|
||||
RealTime[实时数据]
|
||||
Transaction[交易记录]
|
||||
end
|
||||
subgraph "消息转发层"
|
||||
Forwarder[Kafka转发器]
|
||||
Queue[消息队列]
|
||||
end
|
||||
subgraph "应用服务层"
|
||||
App[jcpp-app服务]
|
||||
DB[数据库存储]
|
||||
end
|
||||
TCP --> Session
|
||||
Session --> Processor
|
||||
Processor --> Router
|
||||
Router --> Message
|
||||
Message --> Heartbeat
|
||||
Message --> Login
|
||||
Message --> Charge
|
||||
Message --> RealTime
|
||||
Message --> Transaction
|
||||
Heartbeat --> Forwarder
|
||||
Login --> Forwarder
|
||||
Charge --> Forwarder
|
||||
RealTime --> Forwarder
|
||||
Transaction --> Forwarder
|
||||
Forwarder --> Queue
|
||||
Queue --> App
|
||||
App --> DB
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L27-L61)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L25-L40)
|
||||
|
||||
## 消息处理流程
|
||||
|
||||
### TCP监听器接收数据
|
||||
|
||||
系统从TcpListener接收到原始数据包开始,首先进行基本的完整性检查:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([接收数据包]) --> CheckLength{数据包长度检查}
|
||||
CheckLength --> |长度不足| Reject[拒绝处理]
|
||||
CheckLength --> |长度足够| CheckHeader{头部标识检查}
|
||||
CheckHeader --> |头部无效| Reject
|
||||
CheckHeader --> |头部有效| ParseHeader[解析协议头]
|
||||
ParseHeader --> CheckBoundary{边界检查}
|
||||
CheckBoundary --> |边界无效| Reject
|
||||
CheckBoundary --> |边界有效| ParseFields[解析字段]
|
||||
ParseFields --> CheckCRC{校验和验证}
|
||||
CheckCRC --> |校验失败| Reject
|
||||
CheckCRC --> |校验成功| BuildMessage[构建消息对象]
|
||||
BuildMessage --> RouteCommand[路由命令]
|
||||
RouteCommand --> ExecuteCommand[执行命令]
|
||||
ExecuteCommand --> End([处理完成])
|
||||
Reject --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L63-L154)
|
||||
|
||||
### 消息解析与验证
|
||||
|
||||
协议处理器执行严格的验证流程:
|
||||
|
||||
1. **长度验证**:确保数据包包含最小长度(8字节)
|
||||
2. **头部验证**:检查起始标识符(0x68)
|
||||
3. **边界检查**:验证数据长度字段的合理性
|
||||
4. **CRC校验**:双重校验和验证(小端和大端)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L63-L154)
|
||||
|
||||
### 命令路由与分发
|
||||
|
||||
解析完成后,消息通过命令路由器进行分发:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Processor as 协议处理器
|
||||
participant Router as 命令路由器
|
||||
participant Executor as 命令执行器
|
||||
participant Forwarder as 消息转发器
|
||||
Processor->>Router : 查找命令执行器
|
||||
Router->>Router : 构建路由键(protocol : cmd)
|
||||
Router->>Router : 查询执行器映射表
|
||||
Router-->>Processor : 返回执行器实例
|
||||
Processor->>Executor : 调用execute方法
|
||||
Executor->>Executor : 处理业务逻辑
|
||||
Executor->>Forwarder : 发送消息到队列
|
||||
Forwarder-->>Executor : 确认发送
|
||||
Executor-->>Processor : 返回处理结果
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L170-L184)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L85-L95)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L170-L184)
|
||||
|
||||
## 协议命令注解机制
|
||||
|
||||
### @ProtocolCmd注解设计
|
||||
|
||||
系统采用基于注解的命令映射机制,通过`@ProtocolCmd`注解实现声明式命令注册:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolCmd {
|
||||
+int value()
|
||||
+String[] protocolNames()
|
||||
}
|
||||
class ProtocolCommandRouter {
|
||||
-Map~String,T~ executorMap
|
||||
+ProtocolCommandRouter(Class, Predicate)
|
||||
+getExecutor(String, int) T
|
||||
-initializeRoutes(Class, Predicate)
|
||||
-registerExecutor(Class)
|
||||
}
|
||||
class YunKuaiChongUplinkCmdExe {
|
||||
+execute(TcpSession, YunKuaiChongUplinkMessage, ProtocolContext)
|
||||
#uplinkMessageBuilder(String, TcpSession, YunKuaiChongUplinkMessage)
|
||||
}
|
||||
ProtocolCmd --> YunKuaiChongUplinkCmdExe : 注解标记
|
||||
ProtocolCommandRouter --> YunKuaiChongUplinkCmdExe : 管理实例
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolCmd.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/annotation/ProtocolCmd.java#L20-L32)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L25-L40)
|
||||
|
||||
### 反射机制工作原理
|
||||
|
||||
命令路由器通过以下步骤实现反射机制:
|
||||
|
||||
1. **类扫描**:扫描指定包路径下带有`@ProtocolCmd`注解的类
|
||||
2. **注解解析**:提取命令字和协议名称数组
|
||||
3. **实例化**:动态创建命令执行器实例
|
||||
4. **路由注册**:构建`protocol:cmd`键值对存储到映射表
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L42-L85)
|
||||
|
||||
### 多版本协议支持
|
||||
|
||||
系统通过协议名称数组支持多个协议版本的统一处理:
|
||||
|
||||
| 命令类型 | 协议版本 | 命令字 | 功能描述 |
|
||||
|------|----------------|------|---------|
|
||||
| 心跳命令 | V150/V160/V170 | 0x03 | 充电桩状态报告 |
|
||||
| 登录命令 | V150/V160/V170 | 0x01 | 充电桩认证注册 |
|
||||
| 充电启动 | V150/V160/V170 | 0x31 | 主动充电请求 |
|
||||
| 实时数据 | V150/V160/V170 | 0x13 | 充电过程监控 |
|
||||
| 交易记录 | V150/V160 | 0x3B | 充电完成记录 |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongProtocolConstants.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolConstants.java#L25-L40)
|
||||
|
||||
## 关键上行命令详解
|
||||
|
||||
### 心跳包处理
|
||||
|
||||
心跳命令(0x03)负责维持连接状态和报告充电桩状态:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Pile as 充电桩
|
||||
participant Processor as 协议处理器
|
||||
participant HeartbeatCmd as 心跳命令
|
||||
participant Session as 会话管理
|
||||
participant Forwarder as 消息转发器
|
||||
Pile->>Processor : 发送心跳数据
|
||||
Processor->>HeartbeatCmd : 路由到心跳处理器
|
||||
HeartbeatCmd->>HeartbeatCmd : 解析桩编号和枪状态
|
||||
HeartbeatCmd->>Session : 刷新会话激活状态
|
||||
HeartbeatCmd->>HeartbeatCmd : 构建心跳请求消息
|
||||
HeartbeatCmd->>Forwarder : 发送到Kafka队列
|
||||
HeartbeatCmd->>Pile : 发送心跳响应
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java#L30-L84)
|
||||
|
||||
**业务逻辑特点**:
|
||||
|
||||
- **状态更新**:刷新会话激活时间
|
||||
- **响应机制**:自动回复心跳确认
|
||||
- **信息提取**:解析桩编号、枪号、状态等关键信息
|
||||
- **转发处理**:将心跳信息发送到后端服务
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java#L30-L84)
|
||||
|
||||
### 登录请求处理
|
||||
|
||||
登录命令(0x01)负责充电桩的身份认证和会话建立:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
LoginReq[登录请求] --> ParseInfo[解析设备信息]
|
||||
ParseInfo --> ExtractPileCode[提取桩编号]
|
||||
ExtractPileCode --> ExtractType[提取桩类型]
|
||||
ExtractType --> ExtractGuns[提取枪数量]
|
||||
ExtractGuns --> ExtractVersion[提取软件版本]
|
||||
ExtractVersion --> ExtractSIM[提取SIM卡信息]
|
||||
ExtractSIM --> RegisterSession[注册会话]
|
||||
RegisterSession --> BuildLoginMsg[构建登录消息]
|
||||
BuildLoginMsg --> ForwardToBackend[转发到后端]
|
||||
ForwardToBackend --> Complete[处理完成]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongV150LoginULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150LoginULCmd.java#L30-L84)
|
||||
|
||||
**认证流程**:
|
||||
|
||||
1. **身份验证**:通过桩编号验证设备合法性
|
||||
2. **会话注册**:建立和维护设备会话状态
|
||||
3. **信息收集**:收集设备硬件和软件信息
|
||||
4. **后端通知**:通知应用服务新设备上线
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongV150LoginULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150LoginULCmd.java#L30-L84)
|
||||
|
||||
### 启动充电处理
|
||||
|
||||
充电启动命令(0x31)处理充电桩主动发起的充电请求:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
StartCharge[充电启动请求] --> ParseBasic[解析基础信息]
|
||||
ParseBasic --> ParseCard[解析卡片信息]
|
||||
ParseCard --> ParseVIN[解析VIN码]
|
||||
ParseVIN --> ValidatePassword{需要密码?}
|
||||
ValidatePassword --> |是| HashPassword[密码哈希处理]
|
||||
ValidatePassword --> |否| SkipPassword[跳过密码处理]
|
||||
HashPassword --> ReverseVIN[反转VIN码]
|
||||
SkipPassword --> ReverseVIN
|
||||
ReverseVIN --> BuildRequest[构建启动请求]
|
||||
BuildRequest --> ForwardMessage[转发消息]
|
||||
ForwardMessage --> Complete[处理完成]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongV150StartChargeULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150StartChargeULCmd.java#L35-L124)
|
||||
|
||||
**处理要点**:
|
||||
|
||||
- **卡片验证**:处理物理卡片号和密码验证
|
||||
- **VIN码处理**:特殊格式的VIN码反转处理
|
||||
- **启动方式**:支持多种启动方式(APP、卡片、离线卡等)
|
||||
- **安全机制**:密码MD5哈希处理
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongV150StartChargeULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150StartChargeULCmd.java#L35-L124)
|
||||
|
||||
### 实时数据处理
|
||||
|
||||
实时数据命令(0x13)负责传输充电过程中的监控数据:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class RealTimeDataProcessor {
|
||||
+execute(TcpSession, YunKuaiChongUplinkMessage, ProtocolContext)
|
||||
-parseGunStatus(int, int, String) GunRunStatus
|
||||
-parseFaults(byte[]) boolean[]
|
||||
-getFaultDescriptions(boolean[]) String[]
|
||||
-reduceMagnification(long, int) BigDecimal
|
||||
}
|
||||
class FaultDescription {
|
||||
+急停按钮动作故障
|
||||
+无可用整流模块
|
||||
+出风口温度过高
|
||||
+交流防雷故障
|
||||
+交直流模块通信中断
|
||||
+绝缘检测模块通信中断
|
||||
+电度表通信中断
|
||||
+读卡器通信中断
|
||||
+RC10通信中断
|
||||
+风扇调速板故障
|
||||
+直流熔断器故障
|
||||
+高压接触器故障
|
||||
+门打开
|
||||
}
|
||||
RealTimeDataProcessor --> FaultDescription : 使用
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongV150RealTimeDataULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150RealTimeDataULCmd.java#L35-L239)
|
||||
|
||||
**数据处理能力**:
|
||||
|
||||
- **状态解析**:解析充电枪的各种运行状态
|
||||
- **故障检测**:14种硬件故障的bit位解析
|
||||
- **数值转换**:精密的数值放大倍率处理
|
||||
- **多消息转发**:同时发送状态和进度消息
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongV150RealTimeDataULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150RealTimeDataULCmd.java#L35-L239)
|
||||
|
||||
### 交易记录处理
|
||||
|
||||
交易记录命令(0x3B)处理充电完成后的结算信息:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
TransactionRecord[交易记录] --> ParseTradeNo[解析交易流水号]
|
||||
ParseTradeNo --> ParsePileGun[解析桩号和枪号]
|
||||
ParsePileGun --> ParseTimes[解析时间信息]
|
||||
ParseTimes --> ParseEnergy[解析电量数据]
|
||||
ParseEnergy --> ParseAmount[解析金额信息]
|
||||
ParseAmount --> ParseMeter[解析电表数据]
|
||||
ParseMeter --> ParseVIN[解析VIN码]
|
||||
ParseVIN --> ParseStartFlag[解析启动方式]
|
||||
ParseStartFlag --> ParseStopReason[解析停止原因]
|
||||
ParseStopReason --> ParseCard[解析卡片信息]
|
||||
ParseCard --> BuildTransaction[构建交易记录]
|
||||
BuildTransaction --> ForwardToBackend[转发到后端]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongV150TransactionRecordULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150TransactionRecordULCmd.java#L35-L305)
|
||||
|
||||
**结算信息完整性**:
|
||||
|
||||
- **分时电价**:支持尖峰平谷四种电价模式
|
||||
- **电量统计**:精确到4位小数的电量计量
|
||||
- **费用明细**:详细的电费和服务费计算
|
||||
- **异常处理**:128种充电异常原因的完整映射
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongV150TransactionRecordULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150TransactionRecordULCmd.java#L35-L305)
|
||||
|
||||
## 消息转发机制
|
||||
|
||||
### Kafka转发器架构
|
||||
|
||||
系统采用Kafka作为消息中间件,实现异步消息传递:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "消息生产者"
|
||||
Processor[协议处理器]
|
||||
CmdExe[命令执行器]
|
||||
end
|
||||
subgraph "Kafka集群"
|
||||
Broker1[Kafka Broker 1]
|
||||
Broker2[Kafka Broker 2]
|
||||
Broker3[Kafka Broker 3]
|
||||
end
|
||||
subgraph "消息消费者"
|
||||
Consumer1[jcpp-app服务1]
|
||||
Consumer2[jcpp-app服务2]
|
||||
Consumer3[jcpp-app服务3]
|
||||
end
|
||||
Processor --> CmdExe
|
||||
CmdExe --> KafkaForwarder[Kafka转发器]
|
||||
KafkaForwarder --> Broker1
|
||||
KafkaForwarder --> Broker2
|
||||
KafkaForwarder --> Broker3
|
||||
Broker1 --> Consumer1
|
||||
Broker2 --> Consumer2
|
||||
Broker3 --> Consumer3
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [KafkaForwarder.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/forwarder/KafkaForwarder.java#L40-L80)
|
||||
|
||||
### 消息序列化与传输
|
||||
|
||||
转发器支持多种消息格式和传输模式:
|
||||
|
||||
| 传输模式 | 格式类型 | 性能特点 | 使用场景 |
|
||||
|-----------|----------|------|-------|
|
||||
| Monolith | Protobuf | 高性能 | 单体部署 |
|
||||
| Partition | JSON | 易调试 | 分布式部署 |
|
||||
| Custom | 自定义 | 灵活扩展 | 特殊需求 |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [KafkaForwarder.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/forwarder/KafkaForwarder.java#L120-L180)
|
||||
|
||||
### 消息路由策略
|
||||
|
||||
系统实现了智能的消息路由机制:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Message[上行消息] --> CheckMode{检查传输模式}
|
||||
CheckMode --> |Monolith| DirectSend[直接发送]
|
||||
CheckMode --> |Partition| PartitionSend[分区发送]
|
||||
CheckMode --> |Custom| CustomSend[自定义发送]
|
||||
DirectSend --> MonolithQueue[单体队列]
|
||||
PartitionSend --> PartitionKey[分区键]
|
||||
PartitionKey --> KafkaTopic[Kafka主题]
|
||||
CustomSend --> CustomLogic[自定义逻辑]
|
||||
MonolithQueue --> Consumer[jcpp-app消费者]
|
||||
KafkaTopic --> Consumer
|
||||
CustomLogic --> Consumer
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [KafkaForwarder.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/forwarder/KafkaForwarder.java#L120-L180)
|
||||
|
||||
## 数据持久化与状态管理
|
||||
|
||||
### 属性系统架构
|
||||
|
||||
系统采用属性(Attribute)系统进行数据持久化:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
ENTITY {
|
||||
uuid id PK
|
||||
string entity_type
|
||||
timestamp created_at
|
||||
timestamp last_update_ts
|
||||
}
|
||||
ATTRIBUTE {
|
||||
uuid entity_id FK
|
||||
string attr_key
|
||||
string str_value
|
||||
double dbl_value
|
||||
bigint long_value
|
||||
boolean bool_value
|
||||
json json_value
|
||||
timestamp last_update_ts
|
||||
int version
|
||||
}
|
||||
ENTITY ||--o{ ATTRIBUTE : contains
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [DefaultAttributeRepository.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/dal/repository/attribute/DefaultAttributeRepository.java#L112-L142)
|
||||
|
||||
### 状态更新流程
|
||||
|
||||
系统实现了高效的状态更新机制:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Cmd as 命令处理器
|
||||
participant AttrSvc as 属性服务
|
||||
participant Repo as 属性仓库
|
||||
participant Queue as 批量队列
|
||||
participant DB as 数据库
|
||||
Cmd->>AttrSvc : 请求状态更新
|
||||
AttrSvc->>AttrSvc : 构建属性列表
|
||||
AttrSvc->>Repo : 添加到批量队列
|
||||
Repo->>Queue : 排队等待
|
||||
Queue->>DB : 批量插入/更新
|
||||
DB-->>Queue : 确认写入
|
||||
Queue-->>Repo : 返回版本号
|
||||
Repo-->>AttrSvc : 返回操作结果
|
||||
AttrSvc-->>Cmd : 返回更新状态
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [DefaultAttributeRepository.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/dal/repository/attribute/DefaultAttributeRepository.java#L71-L110)
|
||||
|
||||
### 批量处理优化
|
||||
|
||||
系统采用批量处理策略提升性能:
|
||||
|
||||
| 优化策略 | 实现方式 | 性能提升 |
|
||||
|------|------------------|-----------|
|
||||
| 批量队列 | SqlBlockingQueue | 减少数据库连接开销 |
|
||||
| 异步处理 | Future模式 | 提升并发处理能力 |
|
||||
| 版本控制 | 冲突检测 | 确保数据一致性 |
|
||||
| 缓存机制 | 多级缓存 | 减少重复查询 |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [DefaultAttributeRepository.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/dal/repository/attribute/DefaultAttributeRepository.java#L71-L110)
|
||||
|
||||
## 性能优化策略
|
||||
|
||||
### 异步处理架构
|
||||
|
||||
系统采用完全异步的处理架构:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "网络层"
|
||||
Netty[Netty I/O线程]
|
||||
end
|
||||
subgraph "处理层"
|
||||
Processor[协议处理器]
|
||||
Router[命令路由器]
|
||||
Executor[命令执行器]
|
||||
end
|
||||
subgraph "异步层"
|
||||
AsyncPool[异步线程池]
|
||||
Future[Future模式]
|
||||
end
|
||||
subgraph "存储层"
|
||||
DB[数据库]
|
||||
Cache[缓存]
|
||||
end
|
||||
Netty --> Processor
|
||||
Processor --> Router
|
||||
Router --> Executor
|
||||
Executor --> AsyncPool
|
||||
AsyncPool --> Future
|
||||
Future --> DB
|
||||
Future --> Cache
|
||||
```
|
||||
|
||||
### 内存优化策略
|
||||
|
||||
系统实现了多层次的内存优化:
|
||||
|
||||
| 优化层级 | 策略 | 效果 |
|
||||
|------|---------------|---------|
|
||||
| 对象池 | ByteBuf复用 | 减少GC压力 |
|
||||
| 缓存 | Caffeine本地缓存 | 提升访问速度 |
|
||||
| 序列化 | Protobuf二进制格式 | 减少序列化开销 |
|
||||
| 批量 | 批量操作 | 减少网络往返 |
|
||||
|
||||
### 并发控制机制
|
||||
|
||||
系统采用多种并发控制策略:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Request[请求到达] --> Lock{获取锁}
|
||||
Lock --> |成功| Process[处理请求]
|
||||
Lock --> |失败| Queue[加入队列]
|
||||
Process --> Release[释放锁]
|
||||
Queue --> Wait[等待执行]
|
||||
Wait --> Process
|
||||
Release --> Complete[完成处理]
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
云快充协议上行消息处理系统是一个高度优化的分布式消息处理框架,具有以下核心优势:
|
||||
|
||||
### 技术亮点
|
||||
|
||||
1. **模块化设计**:通过注解驱动的命令路由实现高度可扩展的架构
|
||||
2. **高性能处理**:基于Netty的异步I/O和批量处理策略
|
||||
3. **强一致性**:通过事务性和批量操作保证数据一致性
|
||||
4. **可观测性**:完善的日志记录和监控指标体系
|
||||
|
||||
### 业务价值
|
||||
|
||||
1. **实时响应**:毫秒级的消息处理延迟
|
||||
2. **高可靠性**:多重校验和容错机制
|
||||
3. **可扩展性**:支持多种协议版本和未来扩展
|
||||
4. **运维友好**:清晰的日志和监控界面
|
||||
|
||||
### 应用场景
|
||||
|
||||
该系统适用于大规模充电桩管理平台,能够处理数万甚至数十万充电桩的并发消息处理需求,为电动车充电服务提供稳定可靠的技术支撑。
|
||||
475
docs/核心模块详解/协议实现模块/云快充协议实现/下行消息处理.md
Normal file
475
docs/核心模块详解/协议实现模块/云快充协议实现/下行消息处理.md
Normal file
@@ -0,0 +1,475 @@
|
||||
# 云快充协议下行消息处理链路
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java)
|
||||
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java)
|
||||
- [YunKuaiChongDownlinkCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongDownlinkCmdExe.java)
|
||||
- [YunKuaiChongDownlinkCmdConverter.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/mapping/YunKuaiChongDownlinkCmdConverter.java)
|
||||
- [YunKuaiChongV150RemoteStartDLCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150RemoteStartDLCmd.java)
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java)
|
||||
- [AbstractYunKuaiChongCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/AbstractYunKuaiChongCmdExe.java)
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java)
|
||||
- [TcpChannelHandler.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpChannelHandler.java)
|
||||
- [DownlinkCmdEnum.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/DownlinkCmdEnum.java)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
|
||||
1. [概述](#概述)
|
||||
2. [系统架构](#系统架构)
|
||||
3. [外部接口层](#外部接口层)
|
||||
4. [协议处理层](#协议处理层)
|
||||
5. [命令转换层](#命令转换层)
|
||||
6. [消息构建层](#消息构建层)
|
||||
7. [传输层](#传输层)
|
||||
8. [错误处理与超时机制](#错误处理与超时机制)
|
||||
9. [完整时序图](#完整时序图)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 概述
|
||||
|
||||
云快充协议下行消息处理链路是一个完整的从外部系统发起控制请求到最终发送到充电桩设备的处理流程。该系统支持两种主要的外部接口:REST
|
||||
API 和 gRPC 服务,通过统一的协议处理框架实现对云快充协议的下行指令处理。
|
||||
|
||||
## 系统架构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "外部接口层"
|
||||
REST[REST API<br/>DownlinkController]
|
||||
GRPC[gRPC服务<br/>DownlinkGrpcService]
|
||||
end
|
||||
subgraph "协议处理层"
|
||||
PMM[协议消息处理器<br/>YunKuaiChongProtocolMessageProcessor]
|
||||
DCC[命令转换器<br/>YunKuaiChongDownlinkCmdConverter]
|
||||
DCE[命令执行器基类<br/>AbstractYunKuaiChongCmdExe]
|
||||
end
|
||||
subgraph "命令执行层"
|
||||
RS[远程启动命令<br/>YunKuaiChongV150RemoteStartDLCmd]
|
||||
SS[停止充电命令<br/>YunKuaiChongV150RemoteStopDLCmd]
|
||||
TS[时间同步命令<br/>YunKuaiChongV150TimeSyncDLCmd]
|
||||
end
|
||||
subgraph "传输层"
|
||||
PS[协议会话<br/>ProtocolSession]
|
||||
TC[TCP通道处理器<br/>TcpChannelHandler]
|
||||
CH[通道<br/>Channel]
|
||||
end
|
||||
REST --> PMM
|
||||
GRPC --> PMM
|
||||
PMM --> DCC
|
||||
PMM --> DCE
|
||||
DCE --> RS
|
||||
DCE --> SS
|
||||
DCE --> TS
|
||||
RS --> PS
|
||||
PS --> TC
|
||||
TC --> CH
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L1-L76)
|
||||
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L1-L185)
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L1-L204)
|
||||
|
||||
## 外部接口层
|
||||
|
||||
### REST API 接口
|
||||
|
||||
REST API 提供了一个标准的 HTTP 接口,通过 `/api/onDownlink` 端点接收下行控制请求。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 外部客户端
|
||||
participant Controller as DownlinkController
|
||||
participant Registry as SessionRegistry
|
||||
participant Session as ProtocolSession
|
||||
Client->>Controller : POST /api/onDownlink<br/>protobuf消息
|
||||
Controller->>Controller : 解析消息获取sessionId
|
||||
Controller->>Registry : 获取ProtocolSession
|
||||
Registry-->>Controller : 返回session或null
|
||||
alt session存在
|
||||
Controller->>Session : onDownlink(downlinkMsg)
|
||||
Session-->>Controller : 处理完成
|
||||
Controller-->>Client : 200 OK
|
||||
else session不存在
|
||||
Controller-->>Client : 404 Not Found
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L37-L75)
|
||||
|
||||
### gRPC 服务接口
|
||||
|
||||
gRPC 服务提供了高性能的双向流式通信接口,支持实时的下行控制请求处理。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as gRPC客户端
|
||||
participant Service as DownlinkGrpcService
|
||||
participant Registry as SessionRegistry
|
||||
participant Session as ProtocolSession
|
||||
Client->>Service : onDownlink(stream)<br/>连接请求
|
||||
Service->>Service : 建立连接状态
|
||||
Client->>Service : onDownlink(stream)<br/>下行请求
|
||||
Service->>Service : 解析消息获取sessionId
|
||||
Service->>Registry : 获取ProtocolSession
|
||||
Registry-->>Service : 返回session或null
|
||||
alt session存在
|
||||
Service->>Session : onDownlink(downlinkMsg)
|
||||
Session-->>Service : 处理完成
|
||||
Service-->>Client : 响应确认
|
||||
else session不存在
|
||||
Service-->>Client : 记录日志
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L123-L184)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L1-L76)
|
||||
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L1-L185)
|
||||
|
||||
## 协议处理层
|
||||
|
||||
### 协议消息处理器
|
||||
|
||||
协议消息处理器负责接收来自外部接口的下行请求,并将其转换为内部的消息格式进行处理。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([接收下行请求]) --> ParseMsg["解析DownlinkRequestMessage"]
|
||||
ParseMsg --> ConvertCmd["转换命令类型"]
|
||||
ConvertCmd --> CheckSupport{"命令是否支持?"}
|
||||
CheckSupport --> |否| LogWarn["记录警告日志"]
|
||||
CheckSupport --> |是| CreateMsg["创建YunKuaiChongDwonlinkMessage"]
|
||||
CreateMsg --> GetExecutor["获取命令执行器"]
|
||||
GetExecutor --> ExecutorExists{"执行器是否存在?"}
|
||||
ExecutorExists --> |否| LogInfo["记录未知指令日志"]
|
||||
ExecutorExists --> |是| ExecuteCmd["执行命令"]
|
||||
ExecuteCmd --> End([处理完成])
|
||||
LogWarn --> End
|
||||
LogInfo --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L140-L202)
|
||||
|
||||
### 命令枚举定义
|
||||
|
||||
系统定义了完整的下行命令枚举,涵盖了所有支持的云快充协议指令。
|
||||
|
||||
| 命令类型 | 描述 | 协议支持 |
|
||||
|----------------------------|---------|-------|
|
||||
| LOGIN_ACK | 登录应答 | 全版本 |
|
||||
| HEARTBEAT_ACK | 心跳应答 | 全版本 |
|
||||
| SET_PRICING | 设置定价模型 | V1.5+ |
|
||||
| REMOTE_START_CHARGING | 远程启动充电 | V1.5+ |
|
||||
| REMOTE_STOP_CHARGING | 远程停止充电 | V1.5+ |
|
||||
| TRANSACTION_RECORD_ACK | 交易记录确认 | V1.5+ |
|
||||
| SYNC_TIME_REQUEST | 同步时间请求 | V1.5+ |
|
||||
| OFFLINE_CARD_QUERY_REQUEST | 离线卡查询请求 | V1.5+ |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L1-L204)
|
||||
- [DownlinkCmdEnum.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/DownlinkCmdEnum.java#L1-L55)
|
||||
|
||||
## 命令转换层
|
||||
|
||||
### 命令转换器
|
||||
|
||||
命令转换器负责将通用的 `DownlinkCmdEnum` 转换为云快充协议特定的命令码。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class DownlinkCmdConverter {
|
||||
<<interface>>
|
||||
+convertToCmd(DownlinkCmdEnum) Integer
|
||||
+supports(DownlinkCmdEnum) boolean
|
||||
+getProtocolName() String
|
||||
}
|
||||
class YunKuaiChongDownlinkCmdConverter {
|
||||
-COMMAND_MAP Map~DownlinkCmdEnum,Integer~
|
||||
-INSTANCE YunKuaiChongDownlinkCmdConverter
|
||||
+getInstance() YunKuaiChongDownlinkCmdConverter
|
||||
+convertToCmd(DownlinkCmdEnum) Integer
|
||||
+getProtocolName() String
|
||||
}
|
||||
DownlinkCmdConverter <|-- YunKuaiChongDownlinkCmdConverter
|
||||
note for YunKuaiChongDownlinkCmdConverter "单例模式,使用ConcurrentHashMap存储转换关系\n提供O(1)查找性能"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongDownlinkCmdConverter.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/mapping/YunKuaiChongDownlinkCmdConverter.java#L1-L89)
|
||||
|
||||
### 转换映射表
|
||||
|
||||
以下是部分关键命令的转换映射:
|
||||
|
||||
| 通用命令 | 云快充协议命令码 | 功能描述 |
|
||||
|------------------------|----------|--------|
|
||||
| REMOTE_START_CHARGING | 0x34 | 远程启动充电 |
|
||||
| REMOTE_STOP_CHARGING | 0x36 | 远程停止充电 |
|
||||
| SET_PRICING | 0x58 | 设置定价模型 |
|
||||
| SYNC_TIME_REQUEST | 0x56 | 同步时间请求 |
|
||||
| TRANSACTION_RECORD_ACK | 0x40 | 交易记录确认 |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongDownlinkCmdConverter.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/mapping/YunKuaiChongDownlinkCmdConverter.java#L1-L89)
|
||||
|
||||
## 消息构建层
|
||||
|
||||
### 命令执行器基类
|
||||
|
||||
抽象命令执行器基类提供了消息编码和发送的核心功能。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class AbstractYunKuaiChongCmdExe {
|
||||
-DOWNLINK_CMD_CONVERTER DownlinkCmdConverter
|
||||
+encode(int, int, int, ByteBuf) byte[]
|
||||
+encodeAndWriteFlush(int, int, int, ByteBuf, TcpSession) void
|
||||
+encodeAndWriteFlush(int, ByteBuf, TcpSession) void
|
||||
+encodeAndWriteFlush(DownlinkCmdEnum, int, int, ByteBuf, TcpSession) void
|
||||
+encodeAndWriteFlush(DownlinkCmdEnum, ByteBuf, TcpSession) void
|
||||
+encodePileCode(String) byte[]
|
||||
+encodeGunCode(String) byte[]
|
||||
+encodeTradeNo(String) byte[]
|
||||
+encodeLogicalCardNo(String) byte[]
|
||||
+encodePhysicalCardNo(String) long
|
||||
}
|
||||
class YunKuaiChongV150RemoteStartDLCmd {
|
||||
+execute(TcpSession, YunKuaiChongDwonlinkMessage, ProtocolContext) void
|
||||
}
|
||||
AbstractYunKuaiChongCmdExe <|-- YunKuaiChongV150RemoteStartDLCmd
|
||||
note for AbstractYunKuaiChongCmdExe "提供协议特定的消息编码功能\n包括BCD编码、CRC校验等"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [AbstractYunKuaiChongCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/AbstractYunKuaiChongCmdExe.java#L1-L310)
|
||||
|
||||
### 远程启动命令实现
|
||||
|
||||
以远程启动充电命令为例,展示具体的命令处理流程。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Cmd as YunKuaiChongV150RemoteStartDLCmd
|
||||
participant Base as AbstractYunKuaiChongCmdExe
|
||||
participant Session as TcpSession
|
||||
participant Channel as Netty Channel
|
||||
Cmd->>Cmd : 解析请求参数
|
||||
Note over Cmd : pileCode, gunCode, tradeNo<br/>logicalCardNo, physicalCardNo<br/>limitYuan
|
||||
Cmd->>Cmd : 创建ByteBuf
|
||||
Cmd->>Cmd : 写入交易流水号(32字节BCD)
|
||||
Cmd->>Cmd : 写入桩编码(14字节BCD)
|
||||
Cmd->>Cmd : 写入枪号(2字节BCD)
|
||||
Cmd->>Cmd : 写入逻辑卡号(16字节BCD)
|
||||
Cmd->>Cmd : 写入物理卡号(8字节LE Long)
|
||||
Cmd->>Cmd : 写入账户余额(4字节LE Int)
|
||||
Cmd->>Base : encodeAndWriteFlush(cmd, msgBody, session)
|
||||
Base->>Base : encode(cmd, seqNo, flag, msgBody)
|
||||
Note over Base : 添加协议头、长度、序列号<br/>加密标志、命令字、数据域<br/>计算CRC校验和
|
||||
Base->>Session : writeAndFlush(encodedMessage)
|
||||
Session->>Channel : 发送到网络
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongV150RemoteStartDLCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150RemoteStartDLCmd.java#L1-L72)
|
||||
- [AbstractYunKuaiChongCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/AbstractYunKuaiChongCmdExe.java#L180-L220)
|
||||
|
||||
### 协议消息格式
|
||||
|
||||
云快充协议的下行消息格式如下:
|
||||
|
||||
| 字段 | 长度 | 描述 |
|
||||
|------|-----|-----------------|
|
||||
| 帧头 | 1字节 | 固定值 0x68 |
|
||||
| 数据长度 | 1字节 | 包含后续所有字段的长度 |
|
||||
| 序列号 | 2字节 | LE格式,自动递增 |
|
||||
| 加密标志 | 1字节 | 0表示正常加密 |
|
||||
| 命令字 | 1字节 | 下行命令类型 |
|
||||
| 数据域 | 可变 | 具体命令的数据内容 |
|
||||
| 校验和 | 2字节 | CRC校验,多项式0x180D |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [AbstractYunKuaiChongCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/AbstractYunKuaiChongCmdExe.java#L1-L310)
|
||||
- [YunKuaiChongV150RemoteStartDLCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150RemoteStartDLCmd.java#L1-L72)
|
||||
|
||||
## 传输层
|
||||
|
||||
### 协议会话管理
|
||||
|
||||
协议会话负责维护与充电桩设备的连接状态和消息路由。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolSession {
|
||||
<<abstract>>
|
||||
#protocolName String
|
||||
#id UUID
|
||||
#lastActivityTime LocalDateTime
|
||||
#pileCodeSet Set~String~
|
||||
#requestCache Cache~String,Object~
|
||||
+onDownlink(DownlinkRequestMessage) void
|
||||
+close(SessionCloseReason) void
|
||||
+addPileCode(String) void
|
||||
+addSchedule(String, Function) void
|
||||
}
|
||||
class TcpSession {
|
||||
-sendDownlinkConsumer Consumer~DownlinkRequestMessage~
|
||||
-writeAndFlushConsumer Consumer~ByteBuf~
|
||||
-sequenceNumber AtomicInteger
|
||||
+nextSeqNo(SequenceNumberLength) int
|
||||
+writeAndFlush(ByteBuf) void
|
||||
+onDownlink(DownlinkRequestMessage) void
|
||||
}
|
||||
ProtocolSession <|-- TcpSession
|
||||
note for TcpSession "继承自ProtocolSession<br/>提供TCP连接的下行消息发送功能"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java#L1-L124)
|
||||
- [TcpChannelHandler.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpChannelHandler.java#L30-L128)
|
||||
|
||||
### TCP通道处理器
|
||||
|
||||
TCP通道处理器负责实际的网络数据传输和消息发送。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([消息发送请求]) --> CheckSession{"会话是否有效?"}
|
||||
CheckSession --> |否| LogError["记录错误日志"]
|
||||
CheckSession --> |是| EncodeMsg["编码协议消息"]
|
||||
EncodeMsg --> WriteToChannel["写入Netty Channel"]
|
||||
WriteToChannel --> CheckResult{"发送是否成功?"}
|
||||
CheckResult --> |否| LogFailure["记录发送失败"]
|
||||
CheckResult --> |是| LogSuccess["记录发送成功"]
|
||||
LogError --> End([结束])
|
||||
LogFailure --> End
|
||||
LogSuccess --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [TcpChannelHandler.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpChannelHandler.java#L175-L218)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java#L1-L124)
|
||||
- [TcpChannelHandler.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpChannelHandler.java#L1-L218)
|
||||
|
||||
## 错误处理与超时机制
|
||||
|
||||
### 超时处理
|
||||
|
||||
系统在多个层面实现了超时处理机制:
|
||||
|
||||
1. **HTTP超时**: REST API 默认超时时间为3秒
|
||||
2. **gRPC超时**: 连接建立和消息处理都有超时保护
|
||||
3. **消息发送超时**: TCP通道处理器记录发送时间并监控结果
|
||||
|
||||
### 错误恢复策略
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Error([发生错误]) --> CheckType{"错误类型"}
|
||||
CheckType --> |网络错误| Retry["重试机制"]
|
||||
CheckType --> |协议错误| LogError["记录错误日志"]
|
||||
CheckType --> |超时错误| TimeoutAction["超时处理"]
|
||||
Retry --> RetryCount{"重试次数检查"}
|
||||
RetryCount --> |未超限| DelayRetry["延迟重试"]
|
||||
RetryCount --> |超限| FailFast["快速失败"]
|
||||
DelayRetry --> SendAgain["重新发送"]
|
||||
SendAgain --> Success{"发送成功?"}
|
||||
Success --> |是| LogSuccess["记录成功"]
|
||||
Success --> |否| LogError
|
||||
TimeoutAction --> LogTimeout["记录超时"]
|
||||
LogError --> Cleanup["清理资源"]
|
||||
FailFast --> Cleanup
|
||||
LogSuccess --> Cleanup
|
||||
LogTimeout --> Cleanup
|
||||
Cleanup --> End([结束])
|
||||
```
|
||||
|
||||
### 异常处理机制
|
||||
|
||||
系统提供了完善的异常处理机制,包括:
|
||||
|
||||
- **DownlinkException**: 下行消息处理异常
|
||||
- **IllegalArgumentException**: 参数验证异常
|
||||
- **RuntimeException**: 通用运行时异常处理
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L37-L75)
|
||||
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L123-L184)
|
||||
|
||||
## 完整时序图
|
||||
|
||||
以下展示了从外部系统发起远程启动充电请求到设备响应的完整时序:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 外部客户端
|
||||
participant Controller as DownlinkController
|
||||
participant PMM as 协议消息处理器
|
||||
participant Converter as 命令转换器
|
||||
participant Executor as 命令执行器
|
||||
participant Session as 协议会话
|
||||
participant Channel as TCP通道
|
||||
participant Device as 充电桩设备
|
||||
Note over Client,Device : 远程启动充电流程
|
||||
Client->>Controller : POST /api/onDownlink<br/>RemoteStartChargingRequest
|
||||
Controller->>Controller : 解析protobuf消息
|
||||
Controller->>Session : 获取ProtocolSession
|
||||
Session-->>Controller : 返回会话对象
|
||||
Controller->>PMM : downlinkHandle(sessionToHandlerMsg)
|
||||
PMM->>Converter : convertToCmd(REMOTE_START_CHARGING)
|
||||
Converter-->>PMM : 返回命令码 0x34
|
||||
PMM->>Executor : 获取YunKuaiChongV150RemoteStartDLCmd
|
||||
Executor->>Executor : 解析请求参数
|
||||
Executor->>Executor : 构建消息体
|
||||
Note over Executor : 交易流水号+桩编码+枪号<br/>卡号+余额等信息
|
||||
Executor->>Executor : encodeAndWriteFlush(0x34, msgBody, session)
|
||||
Executor->>Session : writeAndFlush(encodedMessage)
|
||||
Session->>Channel : 发送到网络
|
||||
Channel->>Device : 传输协议消息
|
||||
Device-->>Channel : 设备响应
|
||||
Channel-->>Session : 接收响应
|
||||
Session-->>PMM : 处理上行消息
|
||||
PMM-->>Controller : 处理完成
|
||||
Controller-->>Client : 返回成功响应
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L37-L75)
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L140-L202)
|
||||
- [YunKuaiChongV150RemoteStartDLCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150RemoteStartDLCmd.java#L30-L71)
|
||||
|
||||
## 总结
|
||||
|
||||
云快充协议下行消息处理链路展现了现代工业物联网系统的典型架构特点:
|
||||
|
||||
1. **分层架构**: 清晰的分层设计使得系统具有良好的可维护性和扩展性
|
||||
2. **多接口支持**: 同时支持REST API和gRPC两种接口,满足不同场景需求
|
||||
3. **协议抽象**: 通过命令转换器实现协议无关的设计
|
||||
4. **高效传输**: 基于Netty的异步非阻塞IO,确保高并发处理能力
|
||||
5. **健壮性**: 完善的错误处理和超时机制保证系统稳定性
|
||||
|
||||
该系统为云快充平台提供了可靠、高效的下行指令处理能力,支撑着大规模充电桩的远程控制需求。通过模块化的架构设计和标准化的协议处理流程,系统能够快速适配新的协议版本和功能需求。
|
||||
490
docs/核心模块详解/协议实现模块/云快充协议实现/云快充协议实现.md
Normal file
490
docs/核心模块详解/协议实现模块/云快充协议实现/云快充协议实现.md
Normal file
@@ -0,0 +1,490 @@
|
||||
# 云快充协议实现
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java)
|
||||
- [YunkuaichongV160ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v160/YunkuaichongV160ProtocolBootstrap.java)
|
||||
- [YunkuaichongV170ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v170/YunkuaichongV170ProtocolBootstrap.java)
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java)
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java)
|
||||
- [ProtocolCmd.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/annotation/ProtocolCmd.java)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java)
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java)
|
||||
- [YunKuaiChongDownlinkCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongDownlinkCmdExe.java)
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java)
|
||||
- [TcpChannelHandler.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpChannelHandler.java)
|
||||
- [YunKuaiChongProtocolConstants.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolConstants.java)
|
||||
- [DownlinkCmdEnum.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/DownlinkCmdEnum.java)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [协议版本管理](#协议版本管理)
|
||||
7. [命令处理机制](#命令处理机制)
|
||||
8. [消息编解码流程](#消息编解码流程)
|
||||
9. [性能考虑](#性能考虑)
|
||||
10. [故障排除指南](#故障排除指南)
|
||||
11. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
云快充协议是一个专为电动汽车充电站设计的通信协议实现,采用模块化架构支持多个协议版本(v150、v160、v170),提供了完整的上行和下行消息处理能力。该协议实现了基于Netty的高性能TCP通信,支持心跳检测、远程控制、参数配置等核心功能。
|
||||
|
||||
## 项目结构
|
||||
|
||||
云快充协议的项目结构遵循分层架构设计,主要包含以下模块:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "协议API层"
|
||||
API[Protocol API]
|
||||
Bootstrap[Protocol Bootstrap]
|
||||
MessageProcessor[Message Processor]
|
||||
end
|
||||
subgraph "云快充实现层"
|
||||
V150[Version 1.5.0]
|
||||
V160[Version 1.6.0]
|
||||
V170[Version 1.7.0]
|
||||
Constants[Protocol Constants]
|
||||
end
|
||||
subgraph "命令处理层"
|
||||
UplinkCmd[Uplink Commands]
|
||||
DownlinkCmd[Downlink Commands]
|
||||
Router[Command Router]
|
||||
end
|
||||
API --> Bootstrap
|
||||
Bootstrap --> MessageProcessor
|
||||
MessageProcessor --> V150
|
||||
MessageProcessor --> V160
|
||||
MessageProcessor --> V170
|
||||
V150 --> UplinkCmd
|
||||
V150 --> DownlinkCmd
|
||||
Router --> UplinkCmd
|
||||
Router --> DownlinkCmd
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L1-L127)
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L1-L48)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L1-L48)
|
||||
- [YunkuaichongV160ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v160/YunkuaichongV160ProtocolBootstrap.java#L1-L48)
|
||||
- [YunkuaichongV170ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v170/YunkuaichongV170ProtocolBootstrap.java#L1-L49)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### YunkuaichongV150ProtocolBootstrap
|
||||
|
||||
`YunkuaichongV150ProtocolBootstrap` 是云快充协议的核心入口点,负责协议的初始化和配置。它继承自 `ProtocolBootstrap`
|
||||
,实现了协议的基本生命周期管理。
|
||||
|
||||
#### 主要特性:
|
||||
|
||||
- **协议标识**:使用 `@ProtocolComponent` 注解标记协议名称
|
||||
- **消息处理器**:创建并返回 `YunKuaiChongProtocolMessageProcessor` 实例
|
||||
- **版本支持**:支持 v150、v160、v170 三个版本
|
||||
|
||||
#### 初始化流程:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Bootstrap as YunkuaichongV150ProtocolBootstrap
|
||||
participant Parent as ProtocolBootstrap
|
||||
participant Processor as MessageProcessor
|
||||
participant Listener as TCP Listener
|
||||
Bootstrap->>Parent : init()
|
||||
Parent->>Parent : loadConfig(protocolName)
|
||||
Parent->>Parent : createForwarder()
|
||||
Parent->>Listener : new TcpListener()
|
||||
Bootstrap->>Processor : new YunKuaiChongProtocolMessageProcessor()
|
||||
Processor->>Processor : initializeRouters()
|
||||
Processor-->>Bootstrap : 返回处理器实例
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L30-L47)
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L40-L80)
|
||||
|
||||
### YunKuaiChongProtocolMessageProcessor
|
||||
|
||||
这是协议消息处理的核心组件,负责解析原始字节流并路由到具体的命令处理器。
|
||||
|
||||
#### 核心功能:
|
||||
|
||||
- **上行消息处理**:解析TCP接收到的原始字节流
|
||||
- **下行消息处理**:处理来自REST API的下行请求
|
||||
- **命令路由**:使用 `ProtocolCommandRouter` 进行命令分发
|
||||
- **校验和验证**:支持多种校验和算法
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L30-L47)
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L1-L204)
|
||||
|
||||
## 架构概览
|
||||
|
||||
云快充协议采用分层架构,从底层的网络通信到高层的业务逻辑处理:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用层"
|
||||
REST[REST API Controller]
|
||||
GRPC[gRPC Service]
|
||||
end
|
||||
subgraph "协议层"
|
||||
Bootstrap[Protocol Bootstrap]
|
||||
MessageProcessor[Message Processor]
|
||||
Router[Command Router]
|
||||
end
|
||||
subgraph "传输层"
|
||||
TCP[TCP Listener]
|
||||
ChannelHandler[TCP Channel Handler]
|
||||
end
|
||||
subgraph "网络层"
|
||||
Netty[Netty Framework]
|
||||
Codec[Message Codec]
|
||||
end
|
||||
REST --> Bootstrap
|
||||
GRPC --> Bootstrap
|
||||
Bootstrap --> MessageProcessor
|
||||
MessageProcessor --> Router
|
||||
Router --> ChannelHandler
|
||||
ChannelHandler --> TCP
|
||||
TCP --> Netty
|
||||
Netty --> Codec
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L1-L76)
|
||||
- [TcpChannelHandler.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpChannelHandler.java#L1-L234)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 协议命令注解系统
|
||||
|
||||
`@ProtocolCmd` 注解是云快充协议命令映射的核心机制:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolCmd {
|
||||
+int value()
|
||||
+String[] protocolNames()
|
||||
}
|
||||
class YunKuaiChongV150HeartbeatULCmd {
|
||||
+execute(TcpSession, YunKuaiChongUplinkMessage, ProtocolContext)
|
||||
}
|
||||
class ProtocolCommandRouter {
|
||||
-Map~String,T~ executorMap
|
||||
+getExecutor(String, int) T
|
||||
+registerExecutor(Class)
|
||||
}
|
||||
ProtocolCmd --> YunKuaiChongV150HeartbeatULCmd : "注解"
|
||||
ProtocolCommandRouter --> YunKuaiChongV150HeartbeatULCmd : "路由"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolCmd.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/annotation/ProtocolCmd.java#L1-L33)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L1-L105)
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java#L1-L85)
|
||||
|
||||
#### 注解机制工作原理:
|
||||
|
||||
1. **扫描阶段**:`ProtocolCommandRouter` 使用反射扫描带有 `@ProtocolCmd` 注解的类
|
||||
2. **注册阶段**:将命令字与执行器类建立映射关系
|
||||
3. **路由阶段**:根据协议名称和命令字查找对应的执行器
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [ProtocolCmd.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/annotation/ProtocolCmd.java#L1-L33)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L40-L80)
|
||||
|
||||
### 上行命令处理流程
|
||||
|
||||
上行命令处理是协议的核心功能之一,负责解析设备发送的消息:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([接收TCP消息]) --> ValidateHeader["验证协议头<br/>0x68开头"]
|
||||
ValidateHeader --> ParseLength["解析数据长度字段"]
|
||||
ParseLength --> ValidateBounds["边界检查<br/>确保消息完整"]
|
||||
ValidateBounds --> ExtractFields["提取关键字段<br/>序列号、加密标志、帧类型"]
|
||||
ExtractFields --> ChecksumValidation["校验和验证<br/>支持LE和BE两种格式"]
|
||||
ChecksumValidation --> Success{"校验成功?"}
|
||||
Success --> |否| LogError["记录错误日志"]
|
||||
Success --> |是| ParseBody["解析消息体"]
|
||||
ParseBody --> RouteCommand["路由到命令处理器"]
|
||||
RouteCommand --> ExecuteCmd["执行具体命令"]
|
||||
ExecuteCmd --> End([处理完成])
|
||||
LogError --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L50-L150)
|
||||
|
||||
### 下行命令处理流程
|
||||
|
||||
下行命令处理负责响应REST API请求,向设备发送控制指令:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Controller as DownlinkController
|
||||
participant Session as TcpSession
|
||||
participant Processor as MessageProcessor
|
||||
participant Router as CommandRouter
|
||||
participant Executor as CmdExecutor
|
||||
participant Channel as TCP Channel
|
||||
Controller->>Session : 查找会话
|
||||
Session->>Processor : onDownlink(downlinkMsg)
|
||||
Processor->>Processor : convertToCmd(downlinkCmd)
|
||||
Processor->>Router : getExecutor(protocolName, cmd)
|
||||
Router-->>Processor : 返回执行器
|
||||
Processor->>Executor : execute(session, message, context)
|
||||
Executor->>Executor : encodeAndWriteFlush()
|
||||
Executor->>Channel : 写入TCP缓冲区
|
||||
Channel-->>Controller : 返回响应
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L40-L75)
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L150-L204)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L40-L75)
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L150-L204)
|
||||
|
||||
## 协议版本管理
|
||||
|
||||
云快充协议支持多个版本,每个版本都有自己的 `ProtocolBootstrap` 实现:
|
||||
|
||||
### 版本差异对比
|
||||
|
||||
| 功能特性 | v150 | v160 | v170 |
|
||||
|------|----------|--------|--------|
|
||||
| 基础协议 | ✓ | ✓ | ✓ |
|
||||
| 并行启动 | ✗ | ✓ | ✓ |
|
||||
| 新增命令 | 心跳、登录、对时 | 并行启动命令 | 交易记录命令 |
|
||||
| 向后兼容 | ✓ | ✓ | ✓ |
|
||||
|
||||
### 版本兼容性策略
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "版本兼容性"
|
||||
V150[v1.5.0]
|
||||
V160[v1.6.0]
|
||||
V170[v1.7.0]
|
||||
end
|
||||
subgraph "共享组件"
|
||||
Common[公共命令集]
|
||||
Router[统一路由]
|
||||
Processor[通用处理器]
|
||||
end
|
||||
V150 --> Common
|
||||
V160 --> Common
|
||||
V170 --> Common
|
||||
Common --> Router
|
||||
Router --> Processor
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L20-L25)
|
||||
- [YunkuaichongV160ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v160/YunkuaichongV160ProtocolBootstrap.java#L20-L25)
|
||||
- [YunkuaichongV170ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v170/YunkuaichongV170ProtocolBootstrap.java#L20-L25)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L20-L25)
|
||||
- [YunkuaichongV160ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v160/YunkuaichongV160ProtocolBootstrap.java#L20-L25)
|
||||
- [YunkuaichongV170ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v170/YunkuaichongV170ProtocolBootstrap.java#L20-L25)
|
||||
|
||||
## 命令处理机制
|
||||
|
||||
### 上行命令处理
|
||||
|
||||
以心跳命令为例,展示完整的命令处理流程:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class YunKuaiChongV150HeartbeatULCmd {
|
||||
+execute(TcpSession, YunKuaiChongUplinkMessage, ProtocolContext)
|
||||
-pingAck(TcpSession, YunKuaiChongUplinkMessage, byte[], byte)
|
||||
}
|
||||
class YunKuaiChongUplinkCmdExe {
|
||||
<<abstract>>
|
||||
+execute(TcpSession, YunKuaiChongUplinkMessage, ProtocolContext)*
|
||||
+uplinkMessageBuilder(String, TcpSession, YunKuaiChongUplinkMessage)
|
||||
+encodeAndWriteFlush(DownlinkCmdEnum, int, int, ByteBuf, TcpSession)
|
||||
}
|
||||
class YunKuaiChongUplinkMessage {
|
||||
+int getCmd()
|
||||
+byte[] getMsgBody()
|
||||
+int getSequenceNumber()
|
||||
+int getEncryptionFlag()
|
||||
}
|
||||
YunKuaiChongUplinkCmdExe <|-- YunKuaiChongV150HeartbeatULCmd
|
||||
YunKuaiChongV150HeartbeatULCmd --> YunKuaiChongUplinkMessage : "使用"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java#L25-L85)
|
||||
|
||||
### 下行命令处理
|
||||
|
||||
下行命令处理涉及REST API调用到设备响应的完整流程:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
RESTReq[REST请求] --> Controller[DownlinkController]
|
||||
Controller --> Session[查找TCP会话]
|
||||
Session --> MsgProc[MessageProcessor]
|
||||
MsgProc --> Converter[命令转换器]
|
||||
Converter --> Router[CommandRouter]
|
||||
Router --> Executor[命令执行器]
|
||||
Executor --> Encoder[消息编码]
|
||||
Encoder --> TCP[发送到设备]
|
||||
Controller --> Success[HTTP 200]
|
||||
Controller --> Timeout[HTTP 408]
|
||||
Controller --> NotFound[HTTP 404]
|
||||
Controller --> Error[HTTP 500]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L40-L75)
|
||||
- [YunKuaiChongDownlinkCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongDownlinkCmdExe.java#L1-L19)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java#L25-L85)
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java#L40-L75)
|
||||
|
||||
## 消息编解码流程
|
||||
|
||||
### TCP消息处理
|
||||
|
||||
`TcpChannelHandler` 负责Netty框架层面的消息处理:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Netty as Netty Channel
|
||||
participant Handler as TcpChannelHandler
|
||||
participant Processor as MessageProcessor
|
||||
participant Stats as Metrics
|
||||
Netty->>Handler : channelRead0(msg)
|
||||
Handler->>Handler : process(msg)
|
||||
Handler->>Processor : uplinkHandleAsync()
|
||||
Processor->>Stats : 记录统计信息
|
||||
Processor-->>Handler : 处理完成
|
||||
Handler->>Handler : writeAndFlush()
|
||||
Handler->>Netty : 写入响应
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [TcpChannelHandler.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpChannelHandler.java#L60-L120)
|
||||
|
||||
### 消息格式规范
|
||||
|
||||
云快充协议的消息格式采用固定长度头部加可变长度体的设计:
|
||||
|
||||
| 字段 | 长度 | 描述 |
|
||||
|------|-----|-----------|
|
||||
| 标识符 | 1字节 | 固定值 0x68 |
|
||||
| 数据长度 | 1字节 | 包含头部的总长度 |
|
||||
| 序列号 | 2字节 | 请求-响应配对 |
|
||||
| 加密标志 | 1字节 | 0=明文,1=加密 |
|
||||
| 帧类型 | 1字节 | 命令字 |
|
||||
| 消息体 | 可变 | 具体命令数据 |
|
||||
| 校验和 | 2字节 | CRC校验 |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [TcpChannelHandler.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpChannelHandler.java#L60-L120)
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L50-L150)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 异步处理机制
|
||||
|
||||
协议采用异步处理模式,避免阻塞主线程:
|
||||
|
||||
- **消息队列**:使用Netty的事件循环处理消息
|
||||
- **并发控制**:支持多线程并发处理
|
||||
- **内存优化**:使用ByteBuf进行零拷贝操作
|
||||
|
||||
### 缓存策略
|
||||
|
||||
- **命令路由缓存**:`ProtocolCommandRouter` 使用ConcurrentHashMap缓存命令映射
|
||||
- **会话管理**:TCP会话状态缓存
|
||||
- **统计信息**:实时监控指标缓存
|
||||
|
||||
### 错误处理
|
||||
|
||||
- **快速失败**:无效消息立即丢弃
|
||||
- **优雅降级**:部分功能不可用时保持核心功能
|
||||
- **日志记录**:详细的错误日志便于问题排查
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 1. 协议版本不匹配
|
||||
|
||||
**症状**:设备无法识别命令
|
||||
**解决方案**:检查协议版本配置,确保客户端和服务端版本一致
|
||||
|
||||
#### 2. 校验和错误
|
||||
|
||||
**症状**:日志显示校验失败
|
||||
**解决方案**:检查消息编码和传输过程中的数据完整性
|
||||
|
||||
#### 3. 命令路由失败
|
||||
|
||||
**症状**:未知命令错误日志
|
||||
**解决方案**:确认命令注解配置正确,检查命令处理器注册
|
||||
|
||||
#### 4. TCP连接问题
|
||||
|
||||
**症状**:连接频繁断开
|
||||
**解决方案**:检查网络稳定性,调整心跳间隔配置
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L100-L150)
|
||||
|
||||
## 结论
|
||||
|
||||
云快充协议实现展现了现代通信协议设计的最佳实践:
|
||||
|
||||
### 主要优势
|
||||
|
||||
1. **模块化设计**:清晰的分层架构便于维护和扩展
|
||||
2. **版本兼容性**:支持多版本并保持向后兼容
|
||||
3. **高性能**:基于Netty的异步处理机制
|
||||
4. **可扩展性**:灵活的命令路由机制支持新功能添加
|
||||
5. **可靠性**:完善的错误处理和监控机制
|
||||
|
||||
### 技术特色
|
||||
|
||||
- **注解驱动开发**:简化命令注册和映射
|
||||
- **统一消息处理**:标准化的消息编解码流程
|
||||
- **灵活的版本管理**:支持协议演进和向后兼容
|
||||
- **完善的监控体系**:实时性能监控和错误追踪
|
||||
|
||||
该协议为电动汽车充电站提供了稳定、高效的通信解决方案,具备良好的可维护性和扩展性,能够满足不同场景下的通信需求。
|
||||
444
docs/核心模块详解/协议实现模块/云快充协议实现/核心架构与初始化.md
Normal file
444
docs/核心模块详解/协议实现模块/云快充协议实现/核心架构与初始化.md
Normal file
@@ -0,0 +1,444 @@
|
||||
# 云快充协议核心架构与初始化
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java)
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java)
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java)
|
||||
- [ProtocolMessageProcessor.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolMessageProcessor.java)
|
||||
- [ProtocolContext.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolContext.java)
|
||||
- [TcpListener.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpListener.java)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java)
|
||||
- [YunKuaiChongUplinkMessage.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongUplinkMessage.java)
|
||||
- [YunKuaiChongUplinkCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongUplinkCmdExe.java)
|
||||
- [YunKuaiChongDownlinkCmdExe.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongDownlinkCmdExe.java)
|
||||
- [YunKuaiChongProtocolConstants.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolConstants.java)
|
||||
- [TcpCfg.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/cfg/TcpCfg.java)
|
||||
- [ProtocolCmd.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/annotation/ProtocolCmd.java)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
|
||||
1. [引言](#引言)
|
||||
2. [项目结构概览](#项目结构概览)
|
||||
3. [核心架构设计](#核心架构设计)
|
||||
4. [协议栈初始化流程](#协议栈初始化流程)
|
||||
5. [消息处理机制](#消息处理机制)
|
||||
6. [协议版本管理](#协议版本管理)
|
||||
7. [基础设施组件注入](#基础设施组件注入)
|
||||
8. [性能优化策略](#性能优化策略)
|
||||
9. [故障排除指南](#故障排除指南)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 引言
|
||||
|
||||
云快充协议是JChargePointProtocol项目中的核心通信协议,负责电动汽车充电桩与中央管理系统之间的数据交换。本文档深入解析了云快充协议的核心架构设计,重点阐述了YunkuaichongV150ProtocolBootstrap如何继承ProtocolBootstrap并实现抽象方法,完成协议栈的初始化流程,包括TCP监听器的创建、端口配置、编解码器的注册以及会话管理器的设置。
|
||||
|
||||
## 项目结构概览
|
||||
|
||||
云快充协议采用模块化设计,主要包含以下核心模块:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "协议层"
|
||||
Bootstrap[协议引导器]
|
||||
Processor[消息处理器]
|
||||
Constants[协议常量]
|
||||
end
|
||||
subgraph "版本管理"
|
||||
V150[V150协议]
|
||||
V160[V160协议]
|
||||
V170[V170协议]
|
||||
end
|
||||
subgraph "基础设施"
|
||||
Context[协议上下文]
|
||||
Router[命令路由器]
|
||||
Listener[TCP监听器]
|
||||
end
|
||||
Bootstrap --> Processor
|
||||
Bootstrap --> V150
|
||||
Bootstrap --> V160
|
||||
Bootstrap --> V170
|
||||
Processor --> Router
|
||||
Processor --> Context
|
||||
Bootstrap --> Listener
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L1-L48)
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L1-L50)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L1-L48)
|
||||
- [YunKuaiChongProtocolConstants.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolConstants.java#L1-L44)
|
||||
|
||||
## 核心架构设计
|
||||
|
||||
### 协议引导器层次结构
|
||||
|
||||
云快充协议采用了清晰的分层架构设计,通过继承和组合的方式实现了高度的可扩展性和可维护性:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolBootstrap {
|
||||
<<abstract>>
|
||||
#ProtocolContext protocolContext
|
||||
#ProtocolCfg protocolCfg
|
||||
#Listener listener
|
||||
#Forwarder forwarder
|
||||
+init() void
|
||||
+destroy() void
|
||||
+health() Health
|
||||
#getProtocolName()* String
|
||||
#_init()* void
|
||||
#_destroy()* void
|
||||
#messageProcessor()* ProtocolMessageProcessor
|
||||
}
|
||||
class YunkuaichongV150ProtocolBootstrap {
|
||||
+String PROTOCOL_NAME
|
||||
+getProtocolName() String
|
||||
+_init() void
|
||||
+_destroy() void
|
||||
+messageProcessor() ProtocolMessageProcessor
|
||||
}
|
||||
class YunkuaichongV160ProtocolBootstrap {
|
||||
+String PROTOCOL_NAME
|
||||
+getProtocolName() String
|
||||
+_init() void
|
||||
+_destroy() void
|
||||
+messageProcessor() ProtocolMessageProcessor
|
||||
}
|
||||
class YunkuaichongV170ProtocolBootstrap {
|
||||
+String PROTOCOL_NAME
|
||||
+getProtocolName() String
|
||||
+_init() void
|
||||
+_destroy() void
|
||||
+messageProcessor() ProtocolMessageProcessor
|
||||
}
|
||||
class YunKuaiChongProtocolMessageProcessor {
|
||||
-ProtocolCommandRouter~YunKuaiChongUplinkCmdExe~ uplinkRouter
|
||||
-ProtocolCommandRouter~YunKuaiChongDownlinkCmdExe~ downlinkRouter
|
||||
-DownlinkCmdConverter downlinkCmdConverter
|
||||
+uplinkHandle(ListenerToHandlerMsg) void
|
||||
+doDownlinkHandle(SessionToHandlerMsg) void
|
||||
-exeCmd(YunKuaiChongUplinkMessage, TcpSession) void
|
||||
-exeCmd(YunKuaiChongDwonlinkMessage, TcpSession) void
|
||||
}
|
||||
ProtocolBootstrap <|-- YunkuaichongV150ProtocolBootstrap
|
||||
ProtocolBootstrap <|-- YunkuaichongV160ProtocolBootstrap
|
||||
ProtocolBootstrap <|-- YunkuaichongV170ProtocolBootstrap
|
||||
ProtocolBootstrap --> YunKuaiChongProtocolMessageProcessor
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L25-L127)
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L20-L48)
|
||||
|
||||
### 消息处理架构
|
||||
|
||||
协议的消息处理采用了事件驱动的设计模式,通过命令路由器实现消息的动态路由和处理:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户端设备
|
||||
participant Listener as TCP监听器
|
||||
participant Processor as 消息处理器
|
||||
participant Router as 命令路由器
|
||||
participant Executor as 命令执行器
|
||||
Client->>Listener : 发送原始字节流
|
||||
Listener->>Processor : uplinkHandle(ListenerToHandlerMsg)
|
||||
Processor->>Processor : 解析协议头
|
||||
Processor->>Processor : 校验和验证
|
||||
Processor->>Processor : 构建YunKuaiChongUplinkMessage
|
||||
Processor->>Router : getExecutor(protocolName, cmd)
|
||||
Router->>Executor : 返回对应的命令执行器
|
||||
Executor->>Executor : execute(session, message, context)
|
||||
Executor-->>Processor : 处理结果
|
||||
Processor-->>Listener : 处理完成
|
||||
Listener-->>Client : 响应消息
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L63-L120)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L80-L104)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L27-L61)
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L40-L80)
|
||||
|
||||
## 协议栈初始化流程
|
||||
|
||||
### Bootstrap类的生命周期管理
|
||||
|
||||
YunkuaichongV150ProtocolBootstrap作为协议栈的入口点,继承自ProtocolBootstrap并实现了三个关键的抽象方法:
|
||||
|
||||
#### onInit方法实现
|
||||
|
||||
Bootstrap类的初始化过程遵循严格的生命周期管理原则:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([启动初始化]) --> GetProtocolName["获取协议名称<br/>getProtocolName()"]
|
||||
GetProtocolName --> LoadConfig["加载协议配置<br/>protocolContext.getProtocolsConfigProvider()"]
|
||||
LoadConfig --> CheckForwarder{"检查转发器类型"}
|
||||
CheckForwarder --> |内存模式| CreateMemoryForwarder["创建内存转发器<br/>MemoryForwarder"]
|
||||
CheckForwarder --> |Kafka模式| CreateKafkaForwarder["创建Kafka转发器<br/>KafkaForwarder"]
|
||||
CreateMemoryForwarder --> LoadTcpConfig["加载TCP配置<br/>protocolCfg.getListener().getTcp()"]
|
||||
CreateKafkaForwarder --> LoadTcpConfig
|
||||
LoadTcpConfig --> CreateTcpListener["创建TCP监听器<br/>TcpListener"]
|
||||
CreateTcpListener --> CallOnInit["_init()回调"]
|
||||
CallOnInit --> CreateMessageProcessor["创建消息处理器<br/>messageProcessor()"]
|
||||
CreateMessageProcessor --> Complete([初始化完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L40-L80)
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L25-L47)
|
||||
|
||||
#### onDestroy方法实现
|
||||
|
||||
协议栈的销毁过程同样遵循优雅关闭的原则:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始销毁]) --> LogDestroy["记录销毁日志<br/>log.info('{} destroy...', getProtocolName())"]
|
||||
LogDestroy --> CheckListener{"监听器存在?"}
|
||||
CheckListener --> |是| DestroyListener["销毁TCP监听器<br/>listener.destroy()"]
|
||||
CheckListener --> |否| CheckForwarder{"转发器存在?"}
|
||||
DestroyListener --> CheckForwarder
|
||||
CheckForwarder --> |是| DestroyForwarder["销毁转发器<br/>forwarder.destroy()"]
|
||||
CheckForwarder --> |否| CallOnDestroy["_destroy()回调"]
|
||||
DestroyForwarder --> CallOnDestroy
|
||||
CallOnDestroy --> Complete([销毁完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L82-L95)
|
||||
|
||||
### TCP监听器的创建与配置
|
||||
|
||||
TCP监听器是协议栈的核心组件,负责建立和维护客户端连接:
|
||||
|
||||
#### 监听器配置参数
|
||||
|
||||
| 配置项 | 类型 | 默认值 | 描述 |
|
||||
|------------------------|---------|-----------|---------------|
|
||||
| bindAddress | String | localhost | 绑定地址 |
|
||||
| bindPort | int | 8888 | 监听端口 |
|
||||
| bossGroupThreadCount | int | 1 | Boss线程池大小 |
|
||||
| workerGroupThreadCount | int | 4 | Worker线程池大小 |
|
||||
| soBacklog | int | 100 | 连接队列长度 |
|
||||
| soKeepAlive | boolean | true | TCP保活机制 |
|
||||
| nodelay | boolean | true | TCP_NODELAY选项 |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [TcpListener.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpListener.java#L40-L70)
|
||||
- [TcpCfg.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/cfg/TcpCfg.java#L15-L46)
|
||||
|
||||
## 消息处理机制
|
||||
|
||||
### 原始字节流解析流程
|
||||
|
||||
YunKuaiChongProtocolMessageProcessor的核心职责是将接收到的原始字节流解析为结构化的消息对象:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([接收原始字节流]) --> QuickFail["快速失败检查<br/>长度 & 起始标志"]
|
||||
QuickFail --> ParseHeader["解析协议头<br/>dataLength, seqNo, encryptFlag, frameType"]
|
||||
ParseHeader --> BoundaryCheck["边界检查<br/>dataLength & 可读字节数"]
|
||||
BoundaryCheck --> FieldParse["字段快速解析<br/>序列号、加密标志、帧类型"]
|
||||
FieldParse --> ChecksumCheck["校验和验证<br/>CRC LE & BE两种模式"]
|
||||
ChecksumCheck --> BuildMessage["构建消息对象<br/>YunKuaiChongUplinkMessage"]
|
||||
BuildMessage --> RouteMessage["消息路由<br/>ProtocolCommandRouter"]
|
||||
RouteMessage --> ExecuteCmd["执行命令<br/>命令执行器"]
|
||||
ExecuteCmd --> Complete([处理完成])
|
||||
QuickFail --> |失败| DropMessage["丢弃消息"]
|
||||
BoundaryCheck --> |失败| DropMessage
|
||||
ChecksumCheck --> |失败| DropMessage
|
||||
DropMessage --> Complete
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L63-L120)
|
||||
|
||||
### 消息头信息路由机制
|
||||
|
||||
协议通过消息头中的关键字段进行智能路由:
|
||||
|
||||
| 字段 | 用途 | 路由策略 |
|
||||
|-------------------|-----------|-----------|
|
||||
| 命令码(cmd) | 指定具体操作类型 | 命令路由器精确匹配 |
|
||||
| 序列号(seqNo) | 事务跟踪和响应关联 | 保持会话状态 |
|
||||
| 加密标志(encryptFlag) | 安全级别标识 | 决定后续处理流程 |
|
||||
| 数据长度(dataLength) | 消息完整性验证 | 边界检查和解析控制 |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L85-L120)
|
||||
|
||||
## 协议版本管理
|
||||
|
||||
### 版本兼容性策略
|
||||
|
||||
云快充协议支持多个版本的并存和演进:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "协议版本"
|
||||
V150[V150<br/>基础功能]
|
||||
V160[V160<br/>并行启动]
|
||||
V170[V170<br/>交易记录增强]
|
||||
end
|
||||
subgraph "版本特性"
|
||||
V150Features[登录认证<br/>心跳检测<br/>充电控制]
|
||||
V160Features[远程并行启动<br/>批量操作]
|
||||
V170Features[增强交易记录<br/>详细状态上报]
|
||||
end
|
||||
V150 --> V150Features
|
||||
V160 --> V160Features
|
||||
V170 --> V170Features
|
||||
V150 -.-> V160
|
||||
V160 -.-> V170
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongProtocolConstants.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolConstants.java#L20-L35)
|
||||
|
||||
### 协议常量定义
|
||||
|
||||
每个协议版本都有明确的命名规范和常量定义:
|
||||
|
||||
| 版本 | 常量名 | 协议名称 |
|
||||
|--------|-------------------|------------------|
|
||||
| v1.5.0 | YUNKUAICHONG_V150 | yunkuaichongV150 |
|
||||
| v1.6.0 | YUNKUAICHONG_V160 | yunkuaichongV160 |
|
||||
| v1.7.0 | YUNKUAICHONG_V170 | yunkuaichongV170 |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongProtocolConstants.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolConstants.java#L20-L40)
|
||||
|
||||
## 基础设施组件注入
|
||||
|
||||
### ProtocolContext的作用
|
||||
|
||||
ProtocolContext作为基础设施组件的容器,负责向协议栈注入必要的服务:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolContext {
|
||||
-StatsFactory statsFactory
|
||||
-ProtocolsConfigProvider protocolsConfigProvider
|
||||
-ProtocolSessionRegistryProvider protocolSessionRegistryProvider
|
||||
-ServiceInfoProvider serviceInfoProvider
|
||||
-PartitionProvider partitionProvider
|
||||
-AppQueueFactory appQueueFactory
|
||||
-ShardingThreadPool shardingThreadPool
|
||||
+init() void
|
||||
}
|
||||
class StatsFactory {
|
||||
+createMessagesStats() MessagesStats
|
||||
}
|
||||
class ProtocolsConfigProvider {
|
||||
+loadConfig(protocolName) ProtocolCfg
|
||||
}
|
||||
class ShardingThreadPool {
|
||||
+execute(shardingKey, runnable) void
|
||||
}
|
||||
ProtocolContext --> StatsFactory
|
||||
ProtocolContext --> ProtocolsConfigProvider
|
||||
ProtocolContext --> ShardingThreadPool
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolContext.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolContext.java#L25-L65)
|
||||
|
||||
### 组件依赖关系
|
||||
|
||||
ProtocolContext注入的各个组件在协议栈中发挥着关键作用:
|
||||
|
||||
| 组件 | 用途 | 关键功能 |
|
||||
|-------------------------|------|-------------|
|
||||
| StatsFactory | 性能监控 | 消息统计、健康检查 |
|
||||
| ProtocolsConfigProvider | 配置管理 | 协议配置加载 |
|
||||
| ShardingThreadPool | 并发处理 | 请求分片和线程池管理 |
|
||||
| AppQueueFactory | 消息队列 | 异步消息传递 |
|
||||
| ServiceInfoProvider | 服务发现 | 微服务环境下的服务定位 |
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [ProtocolContext.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolContext.java#L35-L65)
|
||||
|
||||
## 性能优化策略
|
||||
|
||||
### 消息处理优化
|
||||
|
||||
协议栈采用了多种性能优化技术:
|
||||
|
||||
1. **异步处理**: 使用线程池处理上行消息,避免阻塞网络线程
|
||||
2. **零拷贝**: Netty框架的ByteBuf提供了高效的内存管理
|
||||
3. **批量处理**: 支持批量消息处理以提高吞吐量
|
||||
4. **缓存机制**: 命令路由器使用ConcurrentHashMap实现快速查找
|
||||
|
||||
### 内存管理优化
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([消息到达]) --> FastPath["快速路径<br/>长度检查 & 起始标志"]
|
||||
FastPath --> SliceBuffer["切片缓冲区<br/>避免数据复制"]
|
||||
SliceBuffer --> PoolAllocation["池化分配<br/>减少GC压力"]
|
||||
PoolAllocation --> AsyncProcess["异步处理<br/>非阻塞"]
|
||||
AsyncProcess --> ReleaseBuffer["释放缓冲区<br/>及时回收"]
|
||||
ReleaseBuffer --> Complete([处理完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L63-L120)
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题诊断
|
||||
|
||||
1. **连接失败**: 检查TCP监听器配置和防火墙设置
|
||||
2. **消息解析错误**: 验证协议版本兼容性和消息格式
|
||||
3. **性能问题**: 监控线程池使用率和内存分配情况
|
||||
4. **路由失败**: 检查命令执行器的注册状态
|
||||
|
||||
### 日志分析要点
|
||||
|
||||
协议栈提供了详细的日志记录,便于问题诊断:
|
||||
|
||||
- **连接日志**: 记录客户端连接和断开事件
|
||||
- **消息日志**: 记录消息解析和处理过程
|
||||
- **错误日志**: 记录异常情况和失败原因
|
||||
- **性能日志**: 记录处理时间和资源使用情况
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [YunKuaiChongProtocolMessageProcessor.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/YunKuaiChongProtocolMessageProcessor.java#L100-L120)
|
||||
|
||||
## 总结
|
||||
|
||||
云快充协议的核心架构设计体现了现代分布式系统的设计理念:
|
||||
|
||||
1. **模块化设计**: 清晰的分层架构和职责分离
|
||||
2. **可扩展性**: 支持多版本协议并存和演进
|
||||
3. **高性能**: 异步处理和零拷贝优化
|
||||
4. **可靠性**: 完善的错误处理和恢复机制
|
||||
5. **可观测性**: 全面的日志记录和监控指标
|
||||
|
||||
通过YunkuaichongV150ProtocolBootstrap的实现,我们看到了一个典型的协议引导器应该具备的功能:协议栈的初始化、资源管理和生命周期控制。而YunKuaiChongProtocolMessageProcessor则展示了如何高效地处理复杂的协议消息,通过智能路由和优化的解析算法实现高性能的消息处理。
|
||||
|
||||
这种设计不仅满足了当前的业务需求,也为未来的功能扩展和性能优化奠定了坚实的基础。
|
||||
289
docs/核心模块详解/协议实现模块/协议实现模块.md
Normal file
289
docs/核心模块详解/协议实现模块/协议实现模块.md
Normal file
@@ -0,0 +1,289 @@
|
||||
# 协议实现模块
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java)
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java)
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java)
|
||||
- [ProtocolCmd.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/annotation/ProtocolCmd.java)
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java)
|
||||
- [ProtocolMessageProcessor.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolMessageProcessor.java)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java)
|
||||
- [protocol-service.yml](file://jcpp-protocol-bootstrap/src/main/resources/protocol-service.yml)
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java)
|
||||
- [DefaultProtocolsConfigProvider.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/provider/impl/DefaultProtocolsConfigProvider.java)
|
||||
- [ProtocolContext.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolContext.java)
|
||||
- [DownlinkCmdEnum.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/DownlinkCmdEnum.java)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
|
||||
1. [引言](#引言)
|
||||
2. [协议引导类实现](#协议引导类实现)
|
||||
3. [上行命令处理器设计](#上行命令处理器设计)
|
||||
4. [下行指令生成与发送](#下行指令生成与发送)
|
||||
5. [新协议开发指南](#新协议开发指南)
|
||||
6. [协议版本管理策略](#协议版本管理策略)
|
||||
7. [配置文件详解](#配置文件详解)
|
||||
|
||||
## 引言
|
||||
|
||||
本文档旨在为协议实现模块提供详细的开发指南,重点介绍如何基于现有框架扩展新的协议处理功能。通过分析云快充(YunKuaiChong)和绿能(Lvneng)两个具体实现,本文将阐述协议引导类的继承与实现机制、上行命令处理器的设计模式、下行指令的生成与发送流程,并提供新协议开发的分步指南。此外,还将讨论协议版本管理的最佳实践。
|
||||
|
||||
## 协议引导类实现
|
||||
|
||||
本文档分析了云快充和绿能两种协议的引导类实现,它们都继承自`ProtocolBootstrap`抽象类。该基类提供了协议服务初始化、健康检查和资源销毁的通用框架。
|
||||
`YunkuaichongV150ProtocolBootstrap`和`LvnengV340ProtocolBootstrap`通过重写抽象方法,实现了特定于各自协议的初始化配置。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolBootstrap {
|
||||
<<abstract>>
|
||||
+ProtocolContext protocolContext
|
||||
+ProtocolCfg protocolCfg
|
||||
+Listener listener
|
||||
+Forwarder forwarder
|
||||
+init() void
|
||||
+destroy() void
|
||||
+health() Health
|
||||
+getProtocolName() String
|
||||
+_init() void
|
||||
+_destroy() void
|
||||
+messageProcessor() ProtocolMessageProcessor
|
||||
}
|
||||
class YunkuaichongV150ProtocolBootstrap {
|
||||
+PROTOCOL_NAME String
|
||||
+getProtocolName() String
|
||||
+_init() void
|
||||
+_destroy() void
|
||||
+messageProcessor() ProtocolMessageProcessor
|
||||
}
|
||||
class LvnengV340ProtocolBootstrap {
|
||||
+PROTOCOL_NAME String
|
||||
+getProtocolName() String
|
||||
+_init() void
|
||||
+_destroy() void
|
||||
+messageProcessor() ProtocolMessageProcessor
|
||||
}
|
||||
ProtocolBootstrap <|-- YunkuaichongV150ProtocolBootstrap
|
||||
ProtocolBootstrap <|-- LvnengV340ProtocolBootstrap
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java)
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java)
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java)
|
||||
|
||||
**本节来源**
|
||||
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L1-L126)
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L1-L47)
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L1-L41)
|
||||
|
||||
### 云快充V150协议引导类
|
||||
|
||||
`YunkuaichongV150ProtocolBootstrap`是云快充1.5.0版本协议的引导类。它通过`@ProtocolComponent`
|
||||
注解注册到Spring容器中,确保在服务启动时被正确加载。该类的核心是重写`messageProcessor()`方法,返回一个
|
||||
`YunKuaiChongProtocolMessageProcessor`实例,该实例负责处理所有与云快充协议相关的消息编解码和路由。
|
||||
|
||||
### 绿能V340协议引导类
|
||||
|
||||
`LvnengV340ProtocolBootstrap`是绿能3.4.0版本协议的引导类,其结构和实现方式与云快充引导类高度相似。它同样通过
|
||||
`@ProtocolComponent`注解进行注册,并在`messageProcessor()`方法中返回一个`LvnengProtocolMessageProcessor`实例,用于处理绿能协议的特定消息。
|
||||
|
||||
## 上行命令处理器设计
|
||||
|
||||
上行命令处理器的设计采用了基于注解的命令路由模式。核心是`@ProtocolCmd`注解,它将一个命令类与特定的命令字(value)和协议名称(protocolNames)关联起来。
|
||||
`ProtocolCommandRouter`负责在应用启动时扫描所有带有`@ProtocolCmd`注解的类,并构建一个从协议名+命令字到处理器实例的映射表。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 设备 as 充电桩设备
|
||||
participant TcpListener as TcpListener
|
||||
participant ProtocolCommandRouter as ProtocolCommandRouter
|
||||
participant 处理器 as YunKuaiChongV150HeartbeatULCmd
|
||||
设备->>TcpListener : 发送心跳包 (0x03)
|
||||
TcpListener->>ProtocolCommandRouter : 根据协议名和命令字查找处理器
|
||||
ProtocolCommandRouter-->>TcpListener : 返回处理器实例
|
||||
TcpListener->>处理器 : 调用execute方法
|
||||
处理器->>处理器 : 解析消息体,提取桩编码、枪号等信息
|
||||
处理器->>处理器 : 刷新会话状态
|
||||
处理器->>Kafka : 将心跳数据转发到后端
|
||||
处理器->>设备 : 发送心跳响应
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
|
||||
- [ProtocolCmd.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/annotation/ProtocolCmd.java)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java)
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java)
|
||||
|
||||
**本节来源**
|
||||
|
||||
- [ProtocolCmd.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/annotation/ProtocolCmd.java#L1-L32)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L1-L104)
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java#L1-L84)
|
||||
|
||||
### @ProtocolCmd注解详解
|
||||
|
||||
`@ProtocolCmd`注解是命令路由机制的核心。其`value`属性定义了命令的唯一标识(如0x03代表心跳),`protocolNames`
|
||||
属性则指定了该命令适用于哪些协议版本。例如,`YunKuaiChongV150HeartbeatULCmd`的`protocolNames`
|
||||
包含了V150、V160和V170,表明该处理器可以处理这三个版本的心跳包。
|
||||
|
||||
### 心跳包处理器示例
|
||||
|
||||
`YunKuaiChongV150HeartbeatULCmd`是一个典型的上行命令处理器。当设备发送心跳包时,`ProtocolCommandRouter`
|
||||
会根据协议名和命令字0x03找到该处理器。`execute`方法首先解析消息体,提取桩编码、枪号等信息,然后通过
|
||||
`ProtocolSessionRegistryProvider`激活会话,最后将心跳数据封装成Protobuf消息并发送到Kafka主题,同时向设备发送一个心跳响应。
|
||||
|
||||
## 下行指令生成与发送
|
||||
|
||||
下行指令的生成与发送流程始于一个REST API调用。当后端应用需要向充电桩发送指令(如远程启动充电)时,它会调用协议服务的REST接口。该请求最终由
|
||||
`DownlinkController`接收,并通过`ProtocolSession`下发到具体的TCP连接。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 前端 as 前端应用
|
||||
participant DownlinkController as DownlinkController
|
||||
participant ProtocolSession as ProtocolSession
|
||||
participant TcpSession as TcpSession
|
||||
participant 设备 as 充电桩设备
|
||||
前端->>DownlinkController : POST /downlink (远程启动指令)
|
||||
DownlinkController->>ProtocolSession : onDownlink(DownlinkRequestMessage)
|
||||
ProtocolSession->>TcpSession : 获取对应的TCP会话
|
||||
TcpSession->>TcpSession : 根据指令类型查找编码器
|
||||
TcpSession->>TcpSession : 编码指令为二进制流
|
||||
TcpSession->>设备 : 通过TCP连接发送指令
|
||||
设备->>TcpSession : 返回响应
|
||||
TcpSession->>ProtocolSession : 处理响应
|
||||
ProtocolSession->>DownlinkController : 返回执行结果
|
||||
DownlinkController->>前端 : 返回API响应
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
|
||||
- [DownlinkController.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkController.java)
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java)
|
||||
- [TcpSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpSession.java)
|
||||
|
||||
**本节来源**
|
||||
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java#L1-L123)
|
||||
- [ProtocolMessageProcessor.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolMessageProcessor.java#L1-L77)
|
||||
- [DownlinkCmdEnum.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/DownlinkCmdEnum.java#L1-L54)
|
||||
|
||||
### 流程详解
|
||||
|
||||
1. **API调用**:前端或后端服务通过HTTP POST请求调用`/downlink`接口,请求体包含指令类型(如`REMOTE_START_CHARGING`)和相关参数。
|
||||
2. **指令接收**:`DownlinkController`接收到请求,将其转换为`DownlinkRequestMessage`对象。
|
||||
3. **会话查找**:控制器通过`ProtocolSessionRegistryProvider`根据桩编码找到对应的`ProtocolSession`。
|
||||
4. **指令下发**:`ProtocolSession`的`onDownlink`方法被调用,它会将指令委托给底层的`TcpSession`。
|
||||
5. **消息编码**:`TcpSession`根据指令类型(由`DownlinkCmdEnum`定义)查找对应的编码器,将Protobuf消息编码为协议规定的二进制格式。
|
||||
6. **网络发送**:编码后的二进制流通过Netty的`Channel`发送到充电桩设备。
|
||||
7. **响应处理**:设备返回响应后,`TcpSession`会根据响应的命令字触发相应的上行处理器进行处理。
|
||||
|
||||
## 新协议开发指南
|
||||
|
||||
开发一个新协议的实现可以遵循以下分步指南:
|
||||
|
||||
### 第一步:创建Bootstrap类
|
||||
|
||||
1. 在`jcpp-protocol-<your-protocol-name>`模块中创建一个新的包,例如`v100`。
|
||||
2. 创建一个名为`YourProtocolV100Bootstrap`的类,继承`ProtocolBootstrap`。
|
||||
3. 使用`@ProtocolComponent`注解标记该类,并传入协议的唯一名称。
|
||||
4. 重写`getProtocolName()`方法,返回协议名称常量。
|
||||
5. 重写`messageProcessor()`方法,返回一个自定义的`ProtocolMessageProcessor`实现。
|
||||
|
||||
### 第二步:定义消息处理器
|
||||
|
||||
1. 创建一个`cmd`包来存放所有命令处理器。
|
||||
2. 为每个上行命令创建一个处理器类,例如`YourProtocolV100LoginULCmd`。
|
||||
3. 让处理器类继承`AbstractProtocolUplinkCmdExe`或类似基类。
|
||||
4. 使用`@ProtocolCmd`注解标记该类,指定命令字和适用的协议名称。
|
||||
5. 重写`execute`方法,实现消息解析、业务逻辑处理和响应生成。
|
||||
|
||||
### 第三步:配置文件
|
||||
|
||||
1. 在`protocol-service.yml`文件的`service.protocols`节点下,为新协议添加一个配置项。
|
||||
2. 配置`enabled`、`listener.tcp.bind-port`和`forwarder.type`等关键参数。
|
||||
3. 确保`bind-port`不与其他协议冲突。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> CreateBootstrap["创建Bootstrap类<br/>继承ProtocolBootstrap"]
|
||||
CreateBootstrap --> Annotate["使用@ProtocolComponent注解"]
|
||||
Annotate --> OverrideMethods["重写getProtocolName<br/>和messageProcessor方法"]
|
||||
OverrideMethods --> DefineCmd["定义上行命令处理器<br/>在cmd包中"]
|
||||
DefineCmd --> AnnotateCmd["使用@ProtocolCmd注解<br/>指定命令字和协议名"]
|
||||
AnnotateCmd --> ImplementExecute["实现execute方法<br/>处理业务逻辑"]
|
||||
ImplementExecute --> Configure["在protocol-service.yml中<br/>添加协议配置"]
|
||||
Configure --> Test["测试新协议功能"]
|
||||
Test --> End([完成])
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java)
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java)
|
||||
- [protocol-service.yml](file://jcpp-protocol-bootstrap/src/main/resources/protocol-service.yml)
|
||||
|
||||
**本节来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java#L1-L47)
|
||||
- [YunKuaiChongV150HeartbeatULCmd.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/cmd/YunKuaiChongV150HeartbeatULCmd.java#L1-L84)
|
||||
- [protocol-service.yml](file://jcpp-protocol-bootstrap/src/main/resources/protocol-service.yml#L1-L273)
|
||||
|
||||
## 协议版本管理策略
|
||||
|
||||
本框架通过模块化和配置化的方式支持多协议版本管理。每个协议版本都有独立的Bootstrap类和命令处理器,这使得不同版本的协议可以并行运行而互不干扰。
|
||||
|
||||
### 策略一:独立版本模块
|
||||
|
||||
如云快充协议所示,`v150`、`v160`和`v170`分别有独立的`YunkuaichongV150ProtocolBootstrap`、
|
||||
`YunkuaichongV160ProtocolBootstrap`和`YunkuaichongV170ProtocolBootstrap`。每个版本监听不同的TCP端口(38001, 38002,
|
||||
38003),从而实现了物理隔离。
|
||||
|
||||
### 策略二:共享处理器
|
||||
|
||||
对于功能兼容的版本,可以共享部分命令处理器。例如,`YunKuaiChongV150HeartbeatULCmd`的`@ProtocolCmd`注解中`protocolNames`
|
||||
包含了V150、V160和V170,这意味着同一个处理器可以处理这三个版本的心跳包,减少了代码重复。
|
||||
|
||||
### 策略三:配置驱动
|
||||
|
||||
协议的启用、端口、转发器类型等都通过`protocol-service.yml`文件中的配置项控制。通过环境变量(如
|
||||
`PROTOCOLS_YUNKUAICHONGV150_ENABLED`)可以动态地启用或禁用某个协议版本,无需重新编译代码。
|
||||
|
||||
**本节来源**
|
||||
|
||||
- [YunkuaichongV150ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v150/YunkuaichongV150ProtocolBootstrap.java)
|
||||
- [YunkuaichongV160ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v160/YunkuaichongV160ProtocolBootstrap.java)
|
||||
- [YunkuaichongV170ProtocolBootstrap.java](file://jcpp-protocol-yunkuaichong/src/main/java/sanbing/jcpp/protocol/yunkuaichong/v170/YunkuaichongV170ProtocolBootstrap.java)
|
||||
- [protocol-service.yml](file://jcpp-protocol-bootstrap/src/main/resources/protocol-service.yml)
|
||||
|
||||
## 配置文件详解
|
||||
|
||||
`protocol-service.yml`是协议服务的核心配置文件,它定义了所有协议的运行参数。
|
||||
|
||||
### 协议配置结构
|
||||
|
||||
每个协议的配置都位于`service.protocols`节点下,以协议名称(如`yunkuaichongV150`)作为键。其主要包含两个子节点:
|
||||
|
||||
- **listener.tcp**: 定义TCP监听器的配置,包括`bind-address`、`bind-port`、线程池大小和连接超时等。
|
||||
- **forwarder**: 定义消息转发器的配置,包括`type`(kafka或memory)和具体的转发目标(如Kafka主题)。
|
||||
|
||||
### 环境变量注入
|
||||
|
||||
配置文件大量使用了环境变量(如`${PROTOCOLS_YUNKUAICHONGV150_LISTENER_TCP_BIND_PORT:38001}`
|
||||
),这使得服务可以在不同环境中灵活部署。冒号后的值是默认值,当环境变量未设置时使用。
|
||||
|
||||
### 拆包器配置
|
||||
|
||||
`listener.tcp.handler.configuration`是一个关键配置,它定义了Netty的拆包器。例如,云快充协议使用
|
||||
`JCPPLengthFieldBasedFrameDecoder`,并指定了帧头、长度字段偏移量等参数,确保能正确解析设备发送的二进制流。
|
||||
|
||||
**本节来源**
|
||||
|
||||
- [protocol-service.yml](file://jcpp-protocol-bootstrap/src/main/resources/protocol-service.yml#L1-L273)
|
||||
- [DefaultProtocolsConfigProvider.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/provider/impl/DefaultProtocolsConfigProvider.java#L1-L38)
|
||||
- [ProtocolCfg.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/cfg/ProtocolCfg.java#L1-L26)
|
||||
338
docs/核心模块详解/协议实现模块/绿能协议实现/下行消息处理.md
Normal file
338
docs/核心模块详解/协议实现模块/绿能协议实现/下行消息处理.md
Normal file
@@ -0,0 +1,338 @@
|
||||
# 下行消息处理
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [LvnengDownlinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengDownlinkCmdExe.java)
|
||||
- [LvnengDownlinkCmdConverter.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/mapping/LvnengDownlinkCmdConverter.java)
|
||||
- [LvnengV340RemoteStopDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RemoteStopDLCmd.java)
|
||||
- [LvnengV340SetPricingModelDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340SetPricingModelDLCmd.java)
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java)
|
||||
- [DefaultPileProtocolService.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/impl/DefaultPileProtocolService.java)
|
||||
- [TcpSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpSession.java)
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
|
||||
1. [引言](#引言)
|
||||
2. [gRPC调用接收与下行指令生成](#grpc调用接收与下行指令生成)
|
||||
3. [协议命令转换机制](#协议命令转换机制)
|
||||
4. [具体下行命令实现](#具体下行命令实现)
|
||||
5. [消息序列化过程](#消息序列化过程)
|
||||
6. [指令重试与超时处理](#指令重试与超时处理)
|
||||
7. [完整时序图与报文格式示例](#完整时序图与报文格式示例)
|
||||
8. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
|
||||
本文档系统阐述了绿能协议v3.40的下行消息处理流程。重点分析了从gRPC请求到设备响应的完整处理链路,包括LvnengDownlinkCmdExe如何接收gRPC调用并生成相应的下行指令,LvnengDownlinkCmdConverter如何将通用的协议命令转换为绿能协议特有的命令码,以及具体下行命令的实现细节。同时描述了消息序列化过程、指令重试机制和超时处理策略,并提供了完整的时序图和报文格式示例。
|
||||
|
||||
**本文档引用的文件**
|
||||
|
||||
- [LvnengDownlinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengDownlinkCmdExe.java)
|
||||
- [LvnengDownlinkCmdConverter.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/mapping/LvnengDownlinkCmdConverter.java)
|
||||
- [LvnengV340RemoteStopDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RemoteStopDLCmd.java)
|
||||
- [LvnengV340SetPricingModelDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340SetPricingModelDLCmd.java)
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java)
|
||||
- [DefaultPileProtocolService.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/impl/DefaultPileProtocolService.java)
|
||||
- [TcpSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpSession.java)
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java)
|
||||
|
||||
## gRPC调用接收与下行指令生成
|
||||
|
||||
绿能协议v3.40的下行消息处理流程始于gRPC调用的接收。系统通过`DownlinkGrpcService`接收来自客户端的gRPC请求,这些请求被封装为
|
||||
`DownlinkRequestMessage`对象。当gRPC服务接收到请求时,会通过`ProtocolSession`的`onDownlink`方法将消息传递给协议处理器。
|
||||
|
||||
`LvnengProtocolMessageProcessor`作为核心处理器,负责处理所有下行消息。它通过`doDownlinkHandle`方法接收
|
||||
`SessionToHandlerMsg`对象,该对象包含了`DownlinkRequestMessage`和`TcpSession`。处理器首先从`DownlinkRequestMessage`中提取
|
||||
`downlinkCmd`字段,并通过`DownlinkCmdEnum.valueOf()`将其转换为枚举类型。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant GrpcService as "DownlinkGrpcService"
|
||||
participant ProtocolSession as "ProtocolSession"
|
||||
participant MessageProcessor as "LvnengProtocolMessageProcessor"
|
||||
Client->>GrpcService : 发送gRPC请求(DownlinkRequestMessage)
|
||||
GrpcService->>ProtocolSession : 调用onDownlink(DownlinkRequestMessage)
|
||||
ProtocolSession->>MessageProcessor : 传递SessionToHandlerMsg
|
||||
MessageProcessor->>MessageProcessor : 解析DownlinkCmdEnum
|
||||
MessageProcessor->>MessageProcessor : 转换为协议特定命令码
|
||||
MessageProcessor->>MessageProcessor : 执行具体命令处理器
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
|
||||
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L123-L151)
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java#L0-L77)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L0-L186)
|
||||
|
||||
**本文档引用的文件**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java)
|
||||
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java)
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java)
|
||||
|
||||
## 协议命令转换机制
|
||||
|
||||
绿能协议v3.40使用`LvnengDownlinkCmdConverter`类来实现通用协议命令到绿能协议特定命令码的转换。该类实现了
|
||||
`DownlinkCmdConverter`接口,采用单例模式确保全局唯一实例。
|
||||
|
||||
转换器内部使用`ConcurrentHashMap`存储命令映射关系,提供O(1)的查找性能。在静态初始化块中,预定义了绿能协议支持的所有命令映射:
|
||||
|
||||
```java
|
||||
static {
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.LOGIN_ACK, 105);
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.SYNC_TIME_REQUEST, 3);
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.TRANSACTION_RECORD_ACK, 201);
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.HEARTBEAT_ACK, 101);
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.REAL_TIME_DATA_ACK, 103);
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.SET_PRICING, 1103);
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.REMOTE_STOP_CHARGING, 5);
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.SET_QRCODE, 3);
|
||||
}
|
||||
```
|
||||
|
||||
当需要转换命令时,`convertToCmd`方法会根据传入的`DownlinkCmdEnum`
|
||||
返回对应的协议特定命令码。如果命令不被支持,则返回null。这种设计使得命令转换过程高效且易于维护,新增命令只需在静态块中添加映射关系即可。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class DownlinkCmdConverter {
|
||||
<<interface>>
|
||||
+convertToCmd(DownlinkCmdEnum) Integer
|
||||
+supports(DownlinkCmdEnum) boolean
|
||||
+getProtocolName() String
|
||||
}
|
||||
class LvnengDownlinkCmdConverter {
|
||||
-INSTANCE LvnengDownlinkCmdConverter
|
||||
-COMMAND_MAP Map~DownlinkCmdEnum, Integer~
|
||||
+getInstance() LvnengDownlinkCmdConverter
|
||||
+convertToCmd(DownlinkCmdEnum) Integer
|
||||
+getProtocolName() String
|
||||
}
|
||||
DownlinkCmdConverter <|.. LvnengDownlinkCmdConverter
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
|
||||
- [LvnengDownlinkCmdConverter.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/mapping/LvnengDownlinkCmdConverter.java#L0-L75)
|
||||
- [DownlinkCmdConverter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/mapping/DownlinkCmdConverter.java#L0-L44)
|
||||
|
||||
**本文档引用的文件**
|
||||
|
||||
- [LvnengDownlinkCmdConverter.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/mapping/LvnengDownlinkCmdConverter.java)
|
||||
|
||||
## 具体下行命令实现
|
||||
|
||||
### 远程停止充电指令实现
|
||||
|
||||
`LvnengV340RemoteStopDLCmd`类负责处理远程停止充电指令。该类继承自`LvnengDownlinkCmdExe`,并使用`@ProtocolCmd`
|
||||
注解标记其支持的命令码为5,协议版本为V340。
|
||||
|
||||
在`execute`方法中,首先从`LvnengDwonlinkMessage`中提取`RemoteStopChargingRequest`对象,获取充电桩编码和充电枪号。然后构建消息体
|
||||
`ByteBuf`,按照协议规范填充数据:
|
||||
|
||||
1. 写入2字节预留字段(值为0x00)
|
||||
2. 写入1字节充电枪口编号
|
||||
3. 写入4字节启始命令地址(值为2)
|
||||
4. 写入1字节命令个数(值为1)
|
||||
5. 写入2字节命令参数长度(值为4)
|
||||
6. 写入4字节命令参数(值为0x55)
|
||||
|
||||
最后调用`encodeAndWriteFlush`方法将指令发送到设备。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> ExtractData["提取RemoteStopChargingRequest数据"]
|
||||
ExtractData --> CreateBuffer["创建44字节的ByteBuf"]
|
||||
CreateBuffer --> WriteReserved["写入2字节预留字段(0x00)"]
|
||||
WriteReserved --> WriteGunCode["写入充电枪口编号"]
|
||||
WriteGunCode --> WriteStartAddr["写入启始命令地址(2)"]
|
||||
WriteStartAddr --> WriteCmdCount["写入命令个数(1)"]
|
||||
WriteCmdCount --> WriteParamLen["写入命令参数长度(4)"]
|
||||
WriteParamLen --> WriteParam["写入命令参数(0x55)"]
|
||||
WriteParam --> Send["调用encodeAndWriteFlush发送"]
|
||||
Send --> End([结束])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
|
||||
- [LvnengV340RemoteStopDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RemoteStopDLCmd.java#L0-L67)
|
||||
|
||||
**本文档引用的文件**
|
||||
|
||||
- [LvnengV340RemoteStopDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RemoteStopDLCmd.java)
|
||||
|
||||
### 电价设置报文实现
|
||||
|
||||
`LvnengV340SetPricingModelDLCmd`类负责生成电价设置报文。该类同样继承自`LvnengDownlinkCmdExe`,并使用`@ProtocolCmd`
|
||||
注解标记其支持的命令码为1103,协议版本为V340。
|
||||
|
||||
在`execute`方法中,首先从`SetPricingRequest`中提取计费模型信息。对于时段计价模式,遍历所有时间段,将每个时间段的开始时间、结束时间、电费和服务费编码到消息体中:
|
||||
|
||||
1. 将开始时间解析为`LocalTime`对象,分别写入小时和分钟
|
||||
2. 将结束时间解析为`LocalTime`对象,分别写入小时和分钟
|
||||
3. 将电费价格乘以10000后转换为整数,写入4字节
|
||||
4. 将服务费价格乘以10000后转换为整数,写入4字节
|
||||
|
||||
价格转换通过`buildPrice`方法实现,使用`BigDecimal`进行精确计算,避免浮点数精度问题。在发送指令前,将计费ID存入会话的请求缓存中,用于后续的响应匹配。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> ExtractData["提取SetPricingRequest数据"]
|
||||
ExtractData --> CheckPricing["检查计费模式"]
|
||||
CheckPricing --> |时段计价| ProcessPeriods["处理每个时间段"]
|
||||
ProcessPeriods --> ParseStartTime["解析开始时间"]
|
||||
ParseStartTime --> WriteStartHour["写入开始小时"]
|
||||
WriteStartHour --> WriteStartMinute["写入开始分钟"]
|
||||
WriteStartMinute --> ParseEndTime["解析结束时间"]
|
||||
ParseEndTime --> WriteEndHour["写入结束小时"]
|
||||
WriteEndHour --> WriteEndMinute["写入结束分钟"]
|
||||
WriteEndMinute --> ConvertElecPrice["转换电费价格"]
|
||||
ConvertElecPrice --> WriteElecPrice["写入4字节电费"]
|
||||
WriteElecPrice --> ConvertServPrice["转换服务费价格"]
|
||||
ConvertServPrice --> WriteServPrice["写入4字节服务费"]
|
||||
WriteServPrice --> NextPeriod{"还有更多时间段?"}
|
||||
NextPeriod --> |是| ProcessPeriods
|
||||
NextPeriod --> |否| CachePricingId["缓存计费ID"]
|
||||
CachePricingId --> Send["调用encodeAndWriteFlush发送"]
|
||||
Send --> End([结束])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
|
||||
- [LvnengV340SetPricingModelDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340SetPricingModelDLCmd.java#L0-L98)
|
||||
|
||||
**本文档引用的文件**
|
||||
|
||||
- [LvnengV340SetPricingModelDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340SetPricingModelDLCmd.java)
|
||||
|
||||
## 消息序列化过程
|
||||
|
||||
绿能协议v3.40的消息序列化过程由`AbstractLvnengCmdExe`类的`encode`
|
||||
方法实现。该方法按照协议规范构建完整的下行消息帧,格式为:帧头(2) + 长度(2) + 加密标识(1) + 序号(1) + 命令字(2) + 数据域(
|
||||
n) + 校验和(1)。
|
||||
|
||||
序列化过程分为以下几个步骤:
|
||||
|
||||
1. 计算总长度:数据域长度 + 9字节固定头尾
|
||||
2. 构建消息头和数据域:依次写入帧头、长度、加密标识、序号、命令字和数据域
|
||||
3. 准备校验和计算数据:命令字 + 数据域
|
||||
4. 计算并写入校验和:使用`ByteUtil.calculateSum`方法计算累加和
|
||||
5. 转换为字节数组:使用`ByteUtil.toBytes`方法将`ByteBuf`转换为字节数组
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> CalculateLength["计算总长度 = 数据域长度 + 9"]
|
||||
CalculateLength --> BuildHeader["构建消息头"]
|
||||
BuildHeader --> WriteHead["写入帧头(0xAAF5)"]
|
||||
WriteHead --> WriteLength["写入长度(小端序)"]
|
||||
WriteLength --> WriteEncryption["写入加密标识(0x10)"]
|
||||
WriteEncryption --> WriteSeqNo["写入序号"]
|
||||
WriteSeqNo --> WriteCmd["写入命令字(小端序)"]
|
||||
WriteCmd --> WriteData["写入数据域"]
|
||||
WriteData --> PrepareSum["准备校验和数据(命令字+数据域)"]
|
||||
PrepareSum --> CalculateSum["计算累加和(ByteUtil.calculateSum)"]
|
||||
CalculateSum --> WriteSum["写入校验和"]
|
||||
WriteSum --> ConvertBytes["转换为字节数组(ByteUtil.toBytes)"]
|
||||
ConvertBytes --> End([结束])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java#L30-L60)
|
||||
|
||||
**本文档引用的文件**
|
||||
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java)
|
||||
|
||||
## 指令重试与超时处理
|
||||
|
||||
绿能协议v3.40的指令重试与超时处理机制主要通过会话层的请求缓存和定时任务实现。`ProtocolSession`类维护了一个`requestCache`
|
||||
,用于存储待确认的请求。该缓存使用Caffeine构建,具有以下特性:
|
||||
|
||||
- 初始容量:1000
|
||||
- 最大容量:1000
|
||||
- 过期策略:访问后1分钟过期
|
||||
|
||||
当发送下行指令时,相关的请求ID和业务数据会被存入缓存。如果在规定时间内未收到设备的响应,缓存项将自动过期,触发重试逻辑。
|
||||
`TcpSession`类维护了一个原子整数`sequenceNumber`,用于生成消息序号,确保每条消息的唯一性。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolSession {
|
||||
-requestCache Cache~String, Object~
|
||||
+onDownlink(DownlinkRequestMessage)
|
||||
+close(SessionCloseReason)
|
||||
}
|
||||
class TcpSession {
|
||||
-sequenceNumber AtomicInteger
|
||||
+nextSeqNo(SequenceNumberLength)
|
||||
+writeAndFlush(ByteBuf)
|
||||
}
|
||||
ProtocolSession "1" -- "1" TcpSession
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java#L46-L77)
|
||||
- [TcpSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpSession.java#L41-L98)
|
||||
|
||||
**本文档引用的文件**
|
||||
|
||||
- [ProtocolSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/domain/ProtocolSession.java)
|
||||
- [TcpSession.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpSession.java)
|
||||
|
||||
## 完整时序图与报文格式示例
|
||||
|
||||
### 完整时序图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant AppService as "应用服务"
|
||||
participant ProtocolService as "协议服务"
|
||||
participant ProtocolProcessor as "协议处理器"
|
||||
participant Device as "设备"
|
||||
Client->>AppService : 调用setPricing(SetPricingDTO)
|
||||
AppService->>ProtocolService : 构建DownlinkRequestMessage
|
||||
ProtocolService->>ProtocolProcessor : 发送下行消息
|
||||
ProtocolProcessor->>ProtocolProcessor : 转换命令码
|
||||
ProtocolProcessor->>ProtocolProcessor : 构建消息体
|
||||
ProtocolProcessor->>ProtocolProcessor : 序列化消息
|
||||
ProtocolProcessor->>Device : 发送报文
|
||||
Device->>ProtocolProcessor : 返回响应
|
||||
ProtocolProcessor->>ProtocolService : 处理上行消息
|
||||
ProtocolService->>AppService : 通知结果
|
||||
AppService->>Client : 返回成功
|
||||
```
|
||||
|
||||
### 报文格式示例
|
||||
|
||||
以远程停止充电指令为例,完整的报文格式如下:
|
||||
|
||||
| 字段 | 长度(字节) | 值(十六进制) | 说明 |
|
||||
|------|--------|---------------------|----------------------|
|
||||
| 帧头 | 2 | AAF5 | 固定值 |
|
||||
| 长度 | 2 | 002C | 总长度44字节 |
|
||||
| 加密标识 | 1 | 10 | 固定值 |
|
||||
| 序号 | 1 | 01 | 消息序号 |
|
||||
| 命令字 | 2 | 0005 | REMOTE_STOP_CHARGING |
|
||||
| 数据域 | 44 | 0000010200010455... | 消息体 |
|
||||
| 校验和 | 1 | XX | 累加和校验 |
|
||||
|
||||
**本文档引用的文件**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java)
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java)
|
||||
- [LvnengV340RemoteStopDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RemoteStopDLCmd.java)
|
||||
|
||||
## 结论
|
||||
|
||||
本文档详细阐述了绿能协议v3.40的下行消息处理流程。系统通过gRPC接口接收外部请求,经由`LvnengProtocolMessageProcessor`
|
||||
进行命令解析和路由,使用`LvnengDownlinkCmdConverter`将通用命令转换为协议特定命令码,并通过具体的命令执行器(如
|
||||
`LvnengV340RemoteStopDLCmd`和`LvnengV340SetPricingModelDLCmd`
|
||||
)生成相应的下行指令。消息序列化过程严格遵循协议规范,包含帧头、长度、加密标识、序号、命令字、数据域和校验和等字段。指令重试与超时处理通过会话层的请求缓存机制实现,确保了通信的可靠性。整个流程设计合理,模块职责清晰,为充电桩远程控制提供了稳定可靠的基础。
|
||||
522
docs/核心模块详解/协议实现模块/绿能协议实现/核心架构.md
Normal file
522
docs/核心模块详解/协议实现模块/绿能协议实现/核心架构.md
Normal file
@@ -0,0 +1,522 @@
|
||||
# 绿能协议v3.40核心架构设计
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java)
|
||||
- [LvnengProtocolConstants.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolConstants.java)
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java)
|
||||
- [ProtocolMessageProcessor.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolMessageProcessor.java)
|
||||
- [LvnengUplinkMessage.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkMessage.java)
|
||||
- [LvnengDwonlinkMessage.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengDwonlinkMessage.java)
|
||||
- [LvnengUplinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkCmdExe.java)
|
||||
- [LvnengDownlinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengDownlinkCmdExe.java)
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java)
|
||||
- [LvnengV340LoginULCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340LoginULCmd.java)
|
||||
- [LvnengV340RemoteStopDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RemoteStopDLCmd.java)
|
||||
- [TcpListener.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpListener.java)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
|
||||
1. [引言](#引言)
|
||||
2. [项目结构概览](#项目结构概览)
|
||||
3. [核心组件架构](#核心组件架构)
|
||||
4. [协议启动器设计](#协议启动器设计)
|
||||
5. [消息处理机制](#消息处理机制)
|
||||
6. [协议帧结构设计](#协议帧结构设计)
|
||||
7. [命令路由系统](#命令路由系统)
|
||||
8. [组件交互时序](#组件交互时序)
|
||||
9. [性能优化考虑](#性能优化考虑)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 引言
|
||||
|
||||
绿能协议v3.40是JCPP(充电点协议平台)中的一个重要组成部分,专门用于处理绿能品牌的充电设备通信协议。该协议采用模块化设计,通过继承和组合模式实现了高度可扩展的架构。本文档将深入分析其核心架构设计,包括协议启动器、消息处理器、帧结构设计以及组件间的协作机制。
|
||||
|
||||
## 项目结构概览
|
||||
|
||||
绿能协议v3.40的项目结构遵循分层架构原则,主要分为以下几个层次:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用层"
|
||||
Bootstrap[LvnengV340ProtocolBootstrap<br/>协议启动器]
|
||||
end
|
||||
subgraph "业务层"
|
||||
Processor[LvnengProtocolMessageProcessor<br/>消息处理器]
|
||||
Constants[LvnengProtocolConstants<br/>协议常量]
|
||||
end
|
||||
subgraph "命令层"
|
||||
UplinkCmd[LvnengUplinkCmdExe<br/>上行命令基类]
|
||||
DownlinkCmd[LvnengDownlinkCmdExe<br/>下行命令基类]
|
||||
AbstractCmd[AbstractLvnengCmdExe<br/>协议基础类]
|
||||
end
|
||||
subgraph "数据模型层"
|
||||
UplinkMsg[LvnengUplinkMessage<br/>上行消息模型]
|
||||
DownlinkMsg[LvnengDwonlinkMessage<br/>下行消息模型]
|
||||
end
|
||||
subgraph "基础设施层"
|
||||
BaseBootstrap[ProtocolBootstrap<br/>基础启动器]
|
||||
BaseProcessor[ProtocolMessageProcessor<br/>基础消息处理器]
|
||||
Router[ProtocolCommandRouter<br/>命令路由器]
|
||||
end
|
||||
Bootstrap --> Processor
|
||||
Processor --> UplinkCmd
|
||||
Processor --> DownlinkCmd
|
||||
UplinkCmd --> AbstractCmd
|
||||
DownlinkCmd --> AbstractCmd
|
||||
Processor --> UplinkMsg
|
||||
Processor --> DownlinkMsg
|
||||
Bootstrap --> BaseBootstrap
|
||||
Processor --> BaseProcessor
|
||||
Processor --> Router
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L1-L42)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L1-L187)
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L1-L127)
|
||||
|
||||
## 核心组件架构
|
||||
|
||||
### 组件关系图
|
||||
|
||||
绿能协议v3.40的核心架构采用了经典的分层设计模式,各组件之间通过接口进行解耦:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolBootstrap {
|
||||
<<abstract>>
|
||||
+ProtocolContext protocolContext
|
||||
+ProtocolCfg protocolCfg
|
||||
+Listener listener
|
||||
+Forwarder forwarder
|
||||
+init() void
|
||||
+destroy() void
|
||||
#getProtocolName()* String
|
||||
#_init()* void
|
||||
#_destroy()* void
|
||||
#messageProcessor()* ProtocolMessageProcessor
|
||||
}
|
||||
class LvnengV340ProtocolBootstrap {
|
||||
+String PROTOCOL_NAME
|
||||
+getProtocolName() String
|
||||
+_init() void
|
||||
+_destroy() void
|
||||
+messageProcessor() LvnengProtocolMessageProcessor
|
||||
}
|
||||
class ProtocolMessageProcessor {
|
||||
<<abstract>>
|
||||
+Forwarder forwarder
|
||||
+ProtocolContext protocolContext
|
||||
+uplinkHandleAsync() void
|
||||
+downlinkHandle() void
|
||||
#uplinkHandle()* void
|
||||
#doDownlinkHandle()* void
|
||||
}
|
||||
class LvnengProtocolMessageProcessor {
|
||||
-ProtocolCommandRouter~LvnengUplinkCmdExe~ uplinkRouter
|
||||
-ProtocolCommandRouter~LvnengDownlinkCmdExe~ downlinkRouter
|
||||
-DownlinkCmdConverter downlinkCmdConverter
|
||||
+uplinkHandle() void
|
||||
+doDownlinkHandle() void
|
||||
-exeCmd() void
|
||||
}
|
||||
class LvnengUplinkCmdExe {
|
||||
<<abstract>>
|
||||
+execute() void
|
||||
#uplinkMessageBuilder() Builder
|
||||
}
|
||||
class LvnengDownlinkCmdExe {
|
||||
<<abstract>>
|
||||
+execute() void
|
||||
}
|
||||
class AbstractLvnengCmdExe {
|
||||
#encode() byte[]
|
||||
#encodeAndWriteFlush() void
|
||||
}
|
||||
ProtocolBootstrap <|-- LvnengV340ProtocolBootstrap
|
||||
ProtocolMessageProcessor <|-- LvnengProtocolMessageProcessor
|
||||
LvnengUplinkCmdExe <|-- AbstractLvnengCmdExe
|
||||
LvnengDownlinkCmdExe <|-- AbstractLvnengCmdExe
|
||||
LvnengProtocolMessageProcessor --> LvnengUplinkCmdExe
|
||||
LvnengProtocolMessageProcessor --> LvnengDownlinkCmdExe
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L25-L127)
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L15-L42)
|
||||
- [ProtocolMessageProcessor.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolMessageProcessor.java#L20-L78)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L1-L127)
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L1-L42)
|
||||
- [ProtocolMessageProcessor.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolMessageProcessor.java#L1-L78)
|
||||
|
||||
## 协议启动器设计
|
||||
|
||||
### LvnengV340ProtocolBootstrap核心实现
|
||||
|
||||
LvnengV340ProtocolBootstrap作为绿能协议v3.40的主要入口点,继承自ProtocolBootstrap抽象类,并实现了协议特有的初始化和销毁逻辑。
|
||||
|
||||
#### 继承关系与方法实现
|
||||
|
||||
协议启动器通过以下方式实现核心功能:
|
||||
|
||||
1. **协议名称管理**:通过`getProtocolName()`方法返回协议标识
|
||||
2. **初始化逻辑**:重写了`_init()`方法,目前为空实现
|
||||
3. **资源清理**:重写了`_destroy()`方法,目前为空实现
|
||||
4. **消息处理器创建**:通过`messageProcessor()`方法创建具体的处理器实例
|
||||
|
||||
#### 启动流程时序图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as 应用程序
|
||||
participant Bootstrap as LvnengV340ProtocolBootstrap
|
||||
participant Base as ProtocolBootstrap
|
||||
participant Listener as TcpListener
|
||||
participant Forwarder as Forwarder
|
||||
participant Processor as LvnengProtocolMessageProcessor
|
||||
App->>Bootstrap : 实例化启动器
|
||||
App->>Base : 调用init()
|
||||
Base->>Base : 加载协议配置
|
||||
Base->>Forwarder : 创建转发器
|
||||
Base->>Listener : 创建TCP监听器
|
||||
Base->>Bootstrap : 调用_init()
|
||||
Bootstrap-->>Base : 初始化完成
|
||||
Base-->>App : 启动成功
|
||||
Note over App,Processor : 协议运行阶段
|
||||
App->>Listener : 接收客户端连接
|
||||
Listener->>Processor : 处理上行消息
|
||||
Processor->>Processor : 解析协议帧
|
||||
Processor->>Processor : 路由命令处理
|
||||
Processor-->>App : 返回处理结果
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L25-L42)
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L45-L85)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L1-L42)
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L45-L85)
|
||||
|
||||
## 消息处理机制
|
||||
|
||||
### LvnengProtocolMessageProcessor核心功能
|
||||
|
||||
LvnengProtocolMessageProcessor是绿能协议的消息处理中心,负责处理上行和下行消息流。它继承自ProtocolMessageProcessor,并实现了协议特定的消息解析和路由逻辑。
|
||||
|
||||
#### 消息处理架构
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([接收原始消息]) --> ParseHeader[解析帧头信息]
|
||||
ParseHeader --> ValidateLength{验证消息长度}
|
||||
ValidateLength --> |长度异常| LogWarning[记录警告日志]
|
||||
ValidateLength --> |长度正常| ExtractBody[提取消息体]
|
||||
ExtractBody --> VerifyChecksum[验证校验和]
|
||||
VerifyChecksum --> ChecksumValid{校验和有效?}
|
||||
ChecksumValid --> |无效| LogError[记录错误日志]
|
||||
ChecksumValid --> |有效| BuildMessage[构建消息对象]
|
||||
BuildMessage --> RouteCommand[路由命令处理]
|
||||
RouteCommand --> ExecuteCmd[执行命令]
|
||||
ExecuteCmd --> SendResponse[发送响应]
|
||||
LogWarning --> End([处理结束])
|
||||
LogError --> End
|
||||
SendResponse --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L55-L120)
|
||||
|
||||
#### 上行消息处理流程
|
||||
|
||||
上行消息处理包含以下关键步骤:
|
||||
|
||||
1. **帧头解析**:读取起始符、长度、加密标识、序列号和命令码
|
||||
2. **长度验证**:确保消息长度符合最小要求
|
||||
3. **消息体提取**:读取实际的数据内容
|
||||
4. **校验和验证**:使用CRC算法验证数据完整性
|
||||
5. **消息对象构建**:封装为LvnengUplinkMessage对象
|
||||
6. **命令路由**:根据命令类型路由到相应的处理器
|
||||
|
||||
#### 下行消息处理流程
|
||||
|
||||
下行消息处理采用统一的处理模式:
|
||||
|
||||
1. **命令转换**:将通用命令转换为协议特定命令
|
||||
2. **消息构建**:创建LvnengDwonlinkMessage对象
|
||||
3. **命令执行**:调用相应的命令处理器
|
||||
4. **响应发送**:将处理结果发送给客户端
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L55-L187)
|
||||
|
||||
## 协议帧结构设计
|
||||
|
||||
### 帧结构定义
|
||||
|
||||
绿能协议v3.40采用固定格式的帧结构,确保消息的可靠传输和解析:
|
||||
|
||||
| 字段 | 长度(字节) | 描述 |
|
||||
|------|--------|-------------------|
|
||||
| 起始符 | 2 | 固定值0xAAF5,标识帧开始 |
|
||||
| 长度 | 2 | 包含整个帧的总长度(小端序) |
|
||||
| 加密标识 | 1 | 0x10表示加密,0x00表示明文 |
|
||||
| 序列号 | 1 | 用于消息顺序控制 |
|
||||
| 命令码 | 2 | 指示消息类型(小端序) |
|
||||
| 数据域 | 变长 | 实际消息内容 |
|
||||
| 校验和 | 1 | CRC8校验值 |
|
||||
|
||||
#### 帧结构示例
|
||||
|
||||
```
|
||||
+------------------+------------------+------------------+------------------+
|
||||
| 起始符 | 长度 | 加密标识 | 序列号 | 命令码 |
|
||||
| (2字节) | (2字节) | (1字节) | (1字节) | (2字节) |
|
||||
+------------------+------------------+------------------+------------------+
|
||||
| |
|
||||
| 数据域 |
|
||||
| |
|
||||
+---------------------------------------------------------------+
|
||||
| 校验和 |
|
||||
| (1字节) |
|
||||
+--------------+
|
||||
```
|
||||
|
||||
### 校验和算法
|
||||
|
||||
协议采用CRC8算法进行数据完整性验证:
|
||||
|
||||
1. **校验和计算**:对命令码和数据域进行CRC8计算
|
||||
2. **校验和验证**:接收端重新计算并比较
|
||||
3. **错误处理**:校验失败时记录日志并丢弃消息
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L30-L35)
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java#L50-L70)
|
||||
|
||||
## 命令路由系统
|
||||
|
||||
### ProtocolCommandRouter设计
|
||||
|
||||
ProtocolCommandRouter提供了基于协议名和命令字的智能路由功能,支持多版本协议的统一管理:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolCommandRouter {
|
||||
-Map~String,T~ executorMap
|
||||
+ProtocolCommandRouter(scanBaseClass, executorFilter)
|
||||
+getExecutor(protocolName, cmd) T
|
||||
-initializeRoutes() void
|
||||
-registerExecutor() void
|
||||
-buildKey() String
|
||||
}
|
||||
class ProtocolCmd {
|
||||
<<annotation>>
|
||||
+int value()
|
||||
+String[] protocolNames()
|
||||
}
|
||||
class LvnengUplinkCmdExe {
|
||||
<<abstract>>
|
||||
+execute() void
|
||||
}
|
||||
class LvnengV340LoginULCmd {
|
||||
+execute() void
|
||||
}
|
||||
ProtocolCommandRouter --> LvnengUplinkCmdExe
|
||||
LvnengUplinkCmdExe --> ProtocolCmd
|
||||
LvnengV340LoginULCmd --|> LvnengUplinkCmdExe
|
||||
ProtocolCmd --> LvnengV340LoginULCmd
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L25-L105)
|
||||
- [LvnengUplinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkCmdExe.java#L19-L39)
|
||||
|
||||
### 命令执行器层次结构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class AbstractLvnengCmdExe {
|
||||
#byte[] encode()
|
||||
#encodeAndWriteFlush()
|
||||
#DOWNLINK_CMD_CONVERTER
|
||||
#LVNENG_HEAD
|
||||
#LVNENG_ENCRYPTION_FLAG
|
||||
}
|
||||
class LvnengUplinkCmdExe {
|
||||
<<abstract>>
|
||||
+execute() void
|
||||
#uplinkMessageBuilder()
|
||||
}
|
||||
class LvnengDownlinkCmdExe {
|
||||
<<abstract>>
|
||||
+execute() void
|
||||
}
|
||||
class LvnengV340LoginULCmd {
|
||||
+execute() void
|
||||
}
|
||||
class LvnengV340RemoteStopDLCmd {
|
||||
+execute() void
|
||||
}
|
||||
AbstractLvnengCmdExe <|-- LvnengUplinkCmdExe
|
||||
AbstractLvnengCmdExe <|-- LvnengDownlinkCmdExe
|
||||
LvnengUplinkCmdExe <|-- LvnengV340LoginULCmd
|
||||
LvnengDownlinkCmdExe <|-- LvnengV340RemoteStopDLCmd
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java#L18-L120)
|
||||
- [LvnengUplinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkCmdExe.java#L19-L39)
|
||||
- [LvnengDownlinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengDownlinkCmdExe.java#L14-L18)
|
||||
|
||||
### 命令处理时序图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Session as TcpSession
|
||||
participant Processor as LvnengProtocolMessageProcessor
|
||||
participant Router as ProtocolCommandRouter
|
||||
participant Executor as 命令执行器
|
||||
participant Forwarder as Forwarder
|
||||
Session->>Processor : uplinkHandleAsync()
|
||||
Processor->>Processor : 解析消息帧
|
||||
Processor->>Router : getExecutor(protocolName, cmd)
|
||||
Router-->>Processor : 返回命令执行器
|
||||
Processor->>Executor : execute(session, message, context)
|
||||
Executor->>Executor : 处理业务逻辑
|
||||
Executor->>Forwarder : 发送上行消息
|
||||
Forwarder-->>Session : 返回处理结果
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L150-L187)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L25-L105)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L150-L187)
|
||||
|
||||
## 组件交互时序
|
||||
|
||||
### 协议初始化时序
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as 应用程序
|
||||
participant Bootstrap as LvnengV340ProtocolBootstrap
|
||||
participant Config as ProtocolContext
|
||||
participant Forwarder as Forwarder
|
||||
participant Listener as TcpListener
|
||||
participant Processor as LvnengProtocolMessageProcessor
|
||||
App->>Bootstrap : 实例化
|
||||
App->>Bootstrap : init()
|
||||
Bootstrap->>Config : loadConfig(protocolName)
|
||||
Config-->>Bootstrap : 返回配置信息
|
||||
Bootstrap->>Forwarder : 创建转发器
|
||||
Forwarder-->>Bootstrap : 转发器实例
|
||||
Bootstrap->>Listener : 创建TCP监听器
|
||||
Listener->>Processor : 创建消息处理器
|
||||
Processor->>Processor : 初始化命令路由器
|
||||
Processor-->>Listener : 处理器就绪
|
||||
Listener-->>Bootstrap : 监听器就绪
|
||||
Bootstrap->>Bootstrap : _init()
|
||||
Bootstrap-->>App : 初始化完成
|
||||
Note over App,Processor : 协议服务已启动
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L25-L42)
|
||||
- [ProtocolBootstrap.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/ProtocolBootstrap.java#L45-L85)
|
||||
|
||||
### 消息处理时序
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户端
|
||||
participant Listener as TcpListener
|
||||
participant Processor as LvnengProtocolMessageProcessor
|
||||
participant Router as ProtocolCommandRouter
|
||||
participant CmdExe as 命令执行器
|
||||
participant Forwarder as Forwarder
|
||||
Client->>Listener : 发送原始消息
|
||||
Listener->>Processor : uplinkHandleAsync()
|
||||
Processor->>Processor : 解析协议帧
|
||||
Processor->>Processor : 验证校验和
|
||||
Processor->>Router : getExecutor(protocolName, cmd)
|
||||
Router-->>Processor : 返回执行器
|
||||
Processor->>CmdExe : execute(session, message, context)
|
||||
CmdExe->>CmdExe : 处理业务逻辑
|
||||
CmdExe->>Forwarder : sendMessage(uplinkQueueMessage)
|
||||
Forwarder-->>Client : 返回处理结果
|
||||
Note over Client,Forwarder : 异步处理流程
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L55-L120)
|
||||
- [TcpListener.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/listener/tcp/TcpListener.java#L40-L70)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L25-L42)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L55-L120)
|
||||
|
||||
## 性能优化考虑
|
||||
|
||||
### 异步处理机制
|
||||
|
||||
协议采用异步处理模式,通过线程池管理消息处理:
|
||||
|
||||
1. **线程池隔离**:使用分片线程池避免资源竞争
|
||||
2. **异步消息处理**:上行消息处理采用异步模式
|
||||
3. **内存管理**:及时释放ByteBuf资源
|
||||
|
||||
### 内存优化策略
|
||||
|
||||
1. **对象复用**:重用消息对象减少GC压力
|
||||
2. **缓冲区管理**:合理设置TCP缓冲区大小
|
||||
3. **序列号管理**:维护序列号状态避免重复
|
||||
|
||||
### 并发控制
|
||||
|
||||
1. **无锁设计**:使用ConcurrentHashMap实现线程安全
|
||||
2. **原子操作**:利用CAS操作提高并发性能
|
||||
3. **批量处理**:支持批量消息处理
|
||||
|
||||
## 总结
|
||||
|
||||
绿能协议v3.40的核心架构展现了优秀的软件设计原则:
|
||||
|
||||
### 设计亮点
|
||||
|
||||
1. **模块化设计**:清晰的分层架构,职责分离明确
|
||||
2. **可扩展性**:基于注解的命令路由系统,易于添加新命令
|
||||
3. **可靠性**:完善的错误处理和校验机制
|
||||
4. **性能优化**:异步处理和资源管理策略
|
||||
|
||||
### 架构优势
|
||||
|
||||
1. **高内聚低耦合**:各组件职责单一,依赖关系清晰
|
||||
2. **可测试性**:良好的接口设计便于单元测试
|
||||
3. **可维护性**:清晰的代码结构和文档
|
||||
4. **可监控性**:完整的健康检查和统计指标
|
||||
|
||||
该架构为绿能协议v3.40提供了稳定、高效、可扩展的通信基础,能够满足现代充电站系统的复杂需求。
|
||||
526
docs/核心模块详解/协议实现模块/绿能协议实现/绿能协议实现.md
Normal file
526
docs/核心模块详解/协议实现模块/绿能协议实现/绿能协议实现.md
Normal file
@@ -0,0 +1,526 @@
|
||||
# 绿能协议实现
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java)
|
||||
- [LvnengUplinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkCmdExe.java)
|
||||
- [LvnengDownlinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengDownlinkCmdExe.java)
|
||||
- [LvnengDownlinkCmdConverter.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/mapping/LvnengDownlinkCmdConverter.java)
|
||||
- [LvnengV340RealTimeDataULCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RealTimeDataULCmd.java)
|
||||
- [LvnengUplinkMessage.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkMessage.java)
|
||||
- [LvnengDwonlinkMessage.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengDwonlinkMessage.java)
|
||||
- [LvnengProtocolConstants.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolConstants.java)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java)
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java)
|
||||
- [LvnengV340SetPricingModelDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340SetPricingModelDLCmd.java)
|
||||
- [LvnengV340RemoteStopDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RemoteStopDLCmd.java)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [协议消息处理流程](#协议消息处理流程)
|
||||
7. [命令路由机制](#命令路由机制)
|
||||
8. [数据包格式与处理](#数据包格式与处理)
|
||||
9. [实际应用示例](#实际应用示例)
|
||||
10. [性能考虑](#性能考虑)
|
||||
11. [故障排除指南](#故障排除指南)
|
||||
12. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
绿能协议(v3.40)是一个专为电动汽车充电站设计的通信协议,实现了充电桩与服务器之间的可靠数据交换。该协议采用TCP传输层,具有严格的消息帧结构、校验和验证机制和完善的命令处理体系。
|
||||
|
||||
本文档深入分析了绿能协议v3.40的实现细节,重点关注LvnengV340ProtocolBootstrap的配置机制、消息帧结构的设计、以及LvnengProtocolMessageProcessor的处理逻辑。同时详细阐述了上行命令处理器和下行指令生成机制,展示了从gRPC调用到协议报文构建的完整流程。
|
||||
|
||||
## 项目结构
|
||||
|
||||
绿能协议模块采用分层架构设计,主要包含以下核心包结构:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "协议核心模块"
|
||||
A[jcpp-protocol-lvneng]
|
||||
A --> B[v340 - 协议版本实现]
|
||||
A --> C[mapping - 命令映射]
|
||||
A --> D[enums - 枚举定义]
|
||||
A --> E[cmd - 命令处理器]
|
||||
end
|
||||
subgraph "基础框架"
|
||||
F[jcpp-protocol-api]
|
||||
G[jcpp-protocol-bootstrap]
|
||||
H[jcpp-protocol-yunkuaichong]
|
||||
end
|
||||
subgraph "基础设施"
|
||||
I[jcpp-infrastructure-util]
|
||||
J[jcpp-infrastructure-cache]
|
||||
K[jcpp-infrastructure-queue]
|
||||
end
|
||||
A --> F
|
||||
F --> I
|
||||
F --> J
|
||||
F --> K
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L1-L42)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L1-L187)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L1-L42)
|
||||
- [LvnengProtocolConstants.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolConstants.java#L1-L38)
|
||||
|
||||
## 核心组件
|
||||
|
||||
绿能协议的核心组件包括协议引导器、消息处理器、命令执行器和命令转换器等关键模块。这些组件协同工作,实现了完整的协议栈功能。
|
||||
|
||||
### 协议引导器(LvnengV340ProtocolBootstrap)
|
||||
|
||||
协议引导器负责初始化和配置整个协议栈,它继承自基础的ProtocolBootstrap类,提供了协议特定的初始化逻辑。
|
||||
|
||||
### 消息处理器(LvnengProtocolMessageProcessor)
|
||||
|
||||
消息处理器是协议的核心,负责解析和处理所有上行和下行消息。它实现了严格的帧结构解析、校验和验证和命令路由功能。
|
||||
|
||||
### 命令执行器基类
|
||||
|
||||
系统提供了两个抽象基类:LvnengUplinkCmdExe用于处理上行命令,LvnengDownlinkCmdExe用于处理下行命令。它们都继承自AbstractLvnengCmdExe,提供了统一的编码和发送机制。
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L15-L42)
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L25-L50)
|
||||
|
||||
## 架构概览
|
||||
|
||||
绿能协议采用事件驱动的异步处理架构,通过Netty框架实现高效的网络通信。整个架构分为消息接收层、协议处理层、命令执行层和业务逻辑层。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "网络层"
|
||||
A[TCP连接] --> B[消息解码器]
|
||||
B --> C[帧解析器]
|
||||
end
|
||||
subgraph "协议处理层"
|
||||
C --> D[LvnengProtocolMessageProcessor]
|
||||
D --> E[上行命令路由]
|
||||
D --> F[下行命令路由]
|
||||
end
|
||||
subgraph "命令执行层"
|
||||
E --> G[LvnengUplinkCmdExe]
|
||||
F --> H[LvnengDownlinkCmdExe]
|
||||
G --> I[业务逻辑处理]
|
||||
H --> J[协议报文生成]
|
||||
end
|
||||
subgraph "数据转换层"
|
||||
K[LvnengDownlinkCmdConverter] --> H
|
||||
L[消息对象封装] --> G
|
||||
L --> H
|
||||
end
|
||||
subgraph "输出层"
|
||||
I --> M[UplinkQueueMessage]
|
||||
J --> N[编码后的字节数组]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L40-L80)
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L20-L60)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### LvnengV340ProtocolBootstrap配置机制
|
||||
|
||||
LvnengV340ProtocolBootstrap作为协议的入口点,负责建立TCP监听器和初始化协议上下文。它通过注解@ProtocolComponent标记协议名称,并重写父类方法提供具体的初始化逻辑。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class LvnengV340ProtocolBootstrap {
|
||||
+String PROTOCOL_NAME
|
||||
+getProtocolName() String
|
||||
+_init() void
|
||||
+_destroy() void
|
||||
+messageProcessor() ProtocolMessageProcessor
|
||||
}
|
||||
class ProtocolBootstrap {
|
||||
<<abstract>>
|
||||
+forwarder Forwarder
|
||||
+protocolContext ProtocolContext
|
||||
+messageProcessor() ProtocolMessageProcessor
|
||||
}
|
||||
class LvnengProtocolMessageProcessor {
|
||||
+uplinkRouter ProtocolCommandRouter
|
||||
+downlinkRouter ProtocolCommandRouter
|
||||
+downlinkCmdConverter DownlinkCmdConverter
|
||||
+uplinkHandle(ListenerToHandlerMsg) void
|
||||
+doDownlinkHandle(SessionToHandlerMsg) void
|
||||
}
|
||||
LvnengV340ProtocolBootstrap --|> ProtocolBootstrap
|
||||
LvnengV340ProtocolBootstrap --> LvnengProtocolMessageProcessor : creates
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengV340ProtocolBootstrap.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/LvnengV340ProtocolBootstrap.java#L15-L42)
|
||||
|
||||
### 消息帧结构设计
|
||||
|
||||
绿能协议采用严格的帧结构设计,确保消息的可靠传输和完整性验证。帧结构包括起始标志、长度字段、加密标识、序列号、命令字和校验和等关键字段。
|
||||
|
||||
| 字段名称 | 长度(字节) | 描述 |
|
||||
|------|--------|-------------------|
|
||||
| 起始标志 | 2 | 固定值0xAAF5,标识帧开始 |
|
||||
| 数据长度 | 2 | 包含头部和校验和在内的总长度 |
|
||||
| 加密标识 | 1 | 0x10表示加密,0x00表示明文 |
|
||||
| 序列号 | 1 | 用于消息顺序控制 |
|
||||
| 命令字 | 2 | 标识具体命令类型 |
|
||||
| 数据域 | 可变 | 实际消息内容 |
|
||||
| 校验和 | 1 | 对命令字和数据域的校验 |
|
||||
|
||||
### LvnengProtocolMessageProcessor消息处理
|
||||
|
||||
消息处理器实现了复杂的消息解析逻辑,包括帧头解析、长度验证、校验和计算和命令路由等功能。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户端
|
||||
participant Processor as LvnengProtocolMessageProcessor
|
||||
participant Router as 命令路由器
|
||||
participant Executor as 命令执行器
|
||||
participant Forwarder as 消息转发器
|
||||
Client->>Processor : 接收原始消息
|
||||
Processor->>Processor : 解析帧头信息
|
||||
Processor->>Processor : 验证消息长度
|
||||
Processor->>Processor : 读取消息体
|
||||
Processor->>Processor : 计算并验证校验和
|
||||
Processor->>Router : 查找命令执行器
|
||||
Router->>Executor : 返回匹配的执行器
|
||||
Executor->>Executor : 执行业务逻辑
|
||||
Executor->>Forwarder : 转发处理结果
|
||||
Forwarder->>Client : 发送响应消息
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L50-L120)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L25-L187)
|
||||
|
||||
## 协议消息处理流程
|
||||
|
||||
### 上行消息处理流程
|
||||
|
||||
上行消息处理涉及复杂的帧解析和命令执行过程。处理器首先验证消息格式,然后提取各个字段,最后通过命令路由机制找到对应的执行器。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([接收上行消息]) --> ParseHeader["解析帧头信息<br/>起始标志 + 长度 + 加密标识 + 序列号 + 命令字"]
|
||||
ParseHeader --> ValidateLength{"验证消息长度<br/>dataLength >= 9?"}
|
||||
ValidateLength --> |否| LogWarning["记录警告日志"]
|
||||
ValidateLength --> |是| ReadBody["读取消息体<br/>msgBodyLength = dataLength - 9"]
|
||||
ReadBody --> CalcChecksum["计算校验和<br/>sumData = 命令字 + 数据域"]
|
||||
CalcChecksum --> VerifyChecksum{"校验和验证"}
|
||||
VerifyChecksum --> |失败| LogError["记录错误日志"]
|
||||
VerifyChecksum --> |成功| BuildMessage["构建LvnengUplinkMessage对象"]
|
||||
BuildMessage --> RouteCommand["命令路由查找"]
|
||||
RouteCommand --> ExecuteCmd["执行命令处理器"]
|
||||
ExecuteCmd --> SendResponse["发送响应消息"]
|
||||
LogWarning --> End([处理结束])
|
||||
LogError --> End
|
||||
SendResponse --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L50-L120)
|
||||
|
||||
### 下行消息处理流程
|
||||
|
||||
下行消息处理从gRPC调用开始,经过命令转换、消息构建和协议编码等步骤,最终生成符合绿能协议规范的报文。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([接收gRPC调用]) --> ConvertCmd["命令转换<br/>DownlinkCmdEnum -> 协议命令字"]
|
||||
ConvertCmd --> ValidateSupport{"验证命令支持"}
|
||||
ValidateSupport --> |不支持| LogUnsupported["记录不支持命令"]
|
||||
ValidateSupport --> |支持| BuildMessage["构建LvnengDwonlinkMessage"]
|
||||
BuildMessage --> ExtractData["提取请求数据"]
|
||||
ExtractData --> RouteCommand["命令路由查找"]
|
||||
RouteCommand --> ExecuteCmd["执行命令处理器"]
|
||||
ExecuteCmd --> EncodeMsg["编码协议消息<br/>帧头 + 长度 + 加密 + 序列号 + 命令字 + 数据域 + 校验和"]
|
||||
EncodeMsg --> SendMsg["发送到TCP会话"]
|
||||
LogUnsupported --> End([处理结束])
|
||||
SendMsg --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L120-L187)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L50-L187)
|
||||
|
||||
## 命令路由机制
|
||||
|
||||
### ProtocolCommandRouter实现
|
||||
|
||||
ProtocolCommandRouter提供了基于协议名和命令字的智能路由功能,支持自动扫描和注册命令执行器,实现了松耦合的命令处理架构。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProtocolCommandRouter~T~ {
|
||||
-Map~String,T~ executorMap
|
||||
+ProtocolCommandRouter(Class, Predicate)
|
||||
+getExecutor(String, int) T
|
||||
-initializeRoutes(Class, Predicate) void
|
||||
-registerExecutor(Class) void
|
||||
-buildKey(String, int) String
|
||||
}
|
||||
class LvnengUplinkCmdExe {
|
||||
<<abstract>>
|
||||
+execute(TcpSession, LvnengUplinkMessage, ProtocolContext) void
|
||||
#uplinkMessageBuilder(String, TcpSession, LvnengUplinkMessage) UplinkQueueMessage.Builder
|
||||
}
|
||||
class LvnengDownlinkCmdExe {
|
||||
<<abstract>>
|
||||
+execute(TcpSession, LvnengDwonlinkMessage, ProtocolContext) void
|
||||
}
|
||||
class LvnengV340RealTimeDataULCmd {
|
||||
+execute(TcpSession, LvnengUplinkMessage, ProtocolContext) void
|
||||
}
|
||||
class LvnengV340SetPricingModelDLCmd {
|
||||
+execute(TcpSession, LvnengDwonlinkMessage, ProtocolContext) void
|
||||
}
|
||||
ProtocolCommandRouter --> LvnengUplinkCmdExe : routes
|
||||
ProtocolCommandRouter --> LvnengDownlinkCmdExe : routes
|
||||
LvnengUplinkCmdExe <|-- LvnengV340RealTimeDataULCmd
|
||||
LvnengDownlinkCmdExe <|-- LvnengV340SetPricingModelDLCmd
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L20-L105)
|
||||
- [LvnengUplinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkCmdExe.java#L15-L40)
|
||||
|
||||
### 命令注册机制
|
||||
|
||||
系统通过@ProtocolCmd注解自动发现和注册命令执行器,每个执行器可以支持多个协议版本。这种设计使得协议升级更加灵活。
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [ProtocolCommandRouter.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/routing/ProtocolCommandRouter.java#L20-L105)
|
||||
- [LvnengUplinkCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkCmdExe.java#L15-L40)
|
||||
|
||||
## 数据包格式与处理
|
||||
|
||||
### 上行命令处理示例:实时数据上报
|
||||
|
||||
LvnengV340RealTimeDataULCmd展示了典型的上行命令处理流程,包括数据解析、状态更新和消息转发。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Pile as 充电桩
|
||||
participant Cmd as LvnengV340RealTimeDataULCmd
|
||||
participant Session as TCP会话
|
||||
participant Context as 协议上下文
|
||||
participant Forwarder as 消息转发器
|
||||
Pile->>Cmd : 接收实时数据上报
|
||||
Cmd->>Cmd : 解析消息体<br/>充电桩编码 + 枪口数量 + 枪口号
|
||||
Cmd->>Cmd : 提取状态信息<br/>工作状态 + SOC + 告警码
|
||||
Cmd->>Cmd : 解析电气参数<br/>电压、电流、电量
|
||||
Cmd->>Session : 更新会话信息
|
||||
Cmd->>Context : 注册会话
|
||||
Cmd->>Cmd : 构建状态消息<br/>GunRunStatusProto
|
||||
Cmd->>Forwarder : 转发状态信息
|
||||
Cmd->>Cmd : 构建充电进度消息<br/>ChargingProgressProto
|
||||
Cmd->>Forwarder : 转发充电进度
|
||||
Cmd->>Cmd : 发送应答消息<br/>REAL_TIME_DATA_ACK
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengV340RealTimeDataULCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RealTimeDataULCmd.java#L35-L316)
|
||||
|
||||
### 下行命令处理示例:设置定价模型
|
||||
|
||||
LvnengV340SetPricingModelDLCmd演示了下行命令的处理流程,包括参数解析、数据转换和响应生成。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Server as 服务器
|
||||
participant Cmd as LvnengV340SetPricingModelDLCmd
|
||||
participant Session as TCP会话
|
||||
participant Cache as 请求缓存
|
||||
Server->>Cmd : 接收定价模型设置
|
||||
Cmd->>Cmd : 验证消息格式<br/>SetPricingRequest
|
||||
Cmd->>Cmd : 解析计费规则<br/>时段计价或阶梯计价
|
||||
Cmd->>Cmd : 构建响应数据<br/>48个时间段 * 12字节
|
||||
Cmd->>Cache : 存储请求ID
|
||||
Cmd->>Session : 发送应答消息<br/>SET_PRICING_ACK
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengV340SetPricingModelDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340SetPricingModelDLCmd.java#L35-L98)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengV340RealTimeDataULCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340RealTimeDataULCmd.java#L35-L316)
|
||||
- [LvnengV340SetPricingModelDLCmd.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/v340/cmd/LvnengV340SetPricingModelDLCmd.java#L35-L98)
|
||||
|
||||
## 实际应用示例
|
||||
|
||||
### 协议命令转换机制
|
||||
|
||||
LvnengDownlinkCmdConverter作为命令转换器,建立了通用命令与协议特定命令字之间的映射关系。这种设计确保了协议的可扩展性和向后兼容性。
|
||||
|
||||
| 通用命令 | 绿能协议命令字 | 描述 |
|
||||
|------------------------|---------|--------|
|
||||
| LOGIN_ACK | 105 | 登录应答 |
|
||||
| SYNC_TIME_REQUEST | 3 | 时间同步请求 |
|
||||
| TRANSACTION_RECORD_ACK | 201 | 交易记录应答 |
|
||||
| HEARTBEAT_ACK | 101 | 心跳应答 |
|
||||
| REAL_TIME_DATA_ACK | 103 | 实时数据应答 |
|
||||
| SET_PRICING | 1103 | 设置定价模型 |
|
||||
| REMOTE_STOP_CHARGING | 5 | 远程停止充电 |
|
||||
| SET_QRCODE | 3 | 设置二维码 |
|
||||
|
||||
### 消息对象结构
|
||||
|
||||
系统定义了专门的消息对象来封装协议数据,提供了类型安全的数据访问接口。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class LvnengUplinkMessage {
|
||||
-UUID id
|
||||
-int head
|
||||
-int dataLength
|
||||
-int sequenceNumber
|
||||
-int encryptionFlag
|
||||
-int cmd
|
||||
-byte[] msgBody
|
||||
-int checkSum
|
||||
-byte[] rawFrame
|
||||
+getId() UUID
|
||||
+getCmd() int
|
||||
+getMsgBody() byte[]
|
||||
+getRawFrame() byte[]
|
||||
}
|
||||
class LvnengDwonlinkMessage {
|
||||
-UUID id
|
||||
-UUID requestId
|
||||
-int cmd
|
||||
-DownlinkRequestMessage msg
|
||||
-LvnengUplinkMessage requestData
|
||||
+getId() UUID
|
||||
+getCmd() int
|
||||
+getRequestId() UUID
|
||||
+getMsg() DownlinkRequestMessage
|
||||
}
|
||||
class AbstractLvnengCmdExe {
|
||||
#encode(int, int, int, ByteBuf) byte[]
|
||||
#encodeAndWriteFlush(int, ByteBuf, TcpSession) void
|
||||
#encodeAndWriteFlush(DownlinkCmdEnum, ByteBuf, TcpSession) void
|
||||
}
|
||||
LvnengDwonlinkMessage --> LvnengUplinkMessage : requestData
|
||||
AbstractLvnengCmdExe --> LvnengUplinkMessage : processes
|
||||
AbstractLvnengCmdExe --> LvnengDwonlinkMessage : processes
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
|
||||
- [LvnengUplinkMessage.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkMessage.java#L15-L54)
|
||||
- [LvnengDwonlinkMessage.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengDwonlinkMessage.java#L15-L42)
|
||||
- [AbstractLvnengCmdExe.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/AbstractLvnengCmdExe.java#L15-L120)
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengDownlinkCmdConverter.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/mapping/LvnengDownlinkCmdConverter.java#L25-L75)
|
||||
- [LvnengUplinkMessage.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengUplinkMessage.java#L15-L54)
|
||||
- [LvnengDwonlinkMessage.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengDwonlinkMessage.java#L15-L42)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
绿能协议在设计时充分考虑了性能优化,采用了多种技术手段来提高系统的响应速度和吞吐量。
|
||||
|
||||
### 异步处理机制
|
||||
|
||||
系统采用Netty框架实现异步I/O操作,避免了线程阻塞,提高了并发处理能力。消息处理完全基于事件驱动,能够高效处理大量并发连接。
|
||||
|
||||
### 内存管理优化
|
||||
|
||||
- 使用ByteBuf进行零拷贝操作,减少内存分配和垃圾回收压力
|
||||
- 采用对象池技术复用消息对象,降低GC频率
|
||||
- 合理设计消息结构,减少不必要的数据复制
|
||||
|
||||
### 缓存策略
|
||||
|
||||
- 命令路由表采用ConcurrentHashMap实现,提供O(1)的查找性能
|
||||
- 请求ID缓存机制避免重复处理相同请求
|
||||
- 会话状态信息本地化存储,减少数据库访问
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题诊断
|
||||
|
||||
#### 消息解析失败
|
||||
|
||||
- 检查帧头是否为0xAAF5
|
||||
- 验证消息长度是否正确
|
||||
- 确认校验和计算是否准确
|
||||
|
||||
#### 命令路由失败
|
||||
|
||||
- 确认命令执行器是否正确注册
|
||||
- 检查@ProtocolCmd注解配置
|
||||
- 验证协议名称匹配
|
||||
|
||||
#### 连接异常
|
||||
|
||||
- 检查TCP连接状态
|
||||
- 验证网络防火墙设置
|
||||
- 确认端口监听状态
|
||||
|
||||
### 日志分析
|
||||
|
||||
系统提供了详细的日志记录,帮助快速定位问题:
|
||||
|
||||
- WARN级别:消息格式异常、校验和失败
|
||||
- ERROR级别:命令执行异常、系统内部错误
|
||||
- DEBUG级别:消息处理流程跟踪
|
||||
|
||||
**章节来源**
|
||||
|
||||
- [LvnengProtocolMessageProcessor.java](file://jcpp-protocol-lvneng/src/main/java/sanbing/jcpp/protocol/lvneng/LvnengProtocolMessageProcessor.java#L70-L100)
|
||||
|
||||
## 总结
|
||||
|
||||
绿能协议v3.40实现了一个功能完整、性能优异的电动汽车充电站通信协议。通过模块化的架构设计、严格的帧结构规范和智能的命令路由机制,系统实现了高可靠性的消息传输和处理。
|
||||
|
||||
### 主要特性
|
||||
|
||||
1. **严格的协议规范**:采用标准的帧结构和校验机制,确保消息传输的可靠性
|
||||
2. **灵活的命令处理**:支持多种命令类型,具备良好的扩展性
|
||||
3. **高性能架构**:基于Netty的异步处理,支持高并发场景
|
||||
4. **完善的错误处理**:提供详细的日志记录和异常处理机制
|
||||
5. **类型安全设计**:使用强类型的消息对象,减少运行时错误
|
||||
|
||||
### 技术优势
|
||||
|
||||
- **模块化设计**:各组件职责明确,便于维护和扩展
|
||||
- **自动化注册**:通过注解机制自动发现和注册命令执行器
|
||||
- **性能优化**:采用多种优化技术,确保系统高效运行
|
||||
- **向后兼容**:支持协议版本升级,保证系统稳定性
|
||||
|
||||
该协议实现为电动汽车充电站提供了稳定可靠的通信基础,支撑了大规模充电网络的运营需求。通过持续的优化和改进,系统能够适应不断发展的行业需求和技术进步。
|
||||
Reference in New Issue
Block a user