wiki生成

This commit is contained in:
三丙
2025-10-28 14:39:06 +08:00
parent 26cec08d61
commit fa9524d302
31 changed files with 13636 additions and 1 deletions

View File

@@ -0,0 +1,526 @@
# API接口参考
<cite>
**本文档引用的文件**
- [SecurityConfiguration.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/SecurityConfiguration.java)
- [BaseController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/BaseController.java)
- [UserController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/UserController.java)
- [StationController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/StationController.java)
- [PileController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/PileController.java)
- [GunController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/GunController.java)
- [RpcController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/RpcController.java)
- [ProtocolController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/ProtocolController.java)
- [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)
- [ApiResponse.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/ApiResponse.java)
- [LoginResponse.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/LoginResponse.java)
- [JCPPErrorCode.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/exception/JCPPErrorCode.java)
- [JCPPErrorResponseHandler.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/exception/JCPPErrorResponseHandler.java)
- [StationCreateRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/StationCreateRequest.java)
- [PileCreateRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/PileCreateRequest.java)
- [StartChargeDTO.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/dto/StartChargeDTO.java)
- [StopChargeDTO.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/dto/StopChargeDTO.java)
- [RpcRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/RpcRequest.java)
- [downlink.proto](file://jcpp-infrastructure-proto/src/main/proto/downlink.proto)
- [grpc.proto](file://jcpp-infrastructure-proto/src/main/proto/grpc.proto)
</cite>
## 目录
1. [简介](#简介)
2. [RESTful API](#restful-api)
1. [认证与安全](#认证与安全)
2. [设备管理接口](#设备管理接口)
3. [协议管理接口](#协议管理接口)
4. [RPC接口](#rpc接口)
3. [gRPC接口](#grpc接口)
4. [通用响应结构](#通用响应结构)
5. [错误码体系](#错误码体系)
6. [速率限制](#速率限制)
## 简介
本文档为JChargePointProtocol项目提供全面的API接口参考涵盖RESTful API和gRPC两种通信方式。系统为充电桩管理平台提供完整的设备管理、协议交互和远程控制能力。
**Section sources**
- [BaseController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/BaseController.java)
## RESTful API
### 认证与安全
系统采用JWTJSON Web Token进行身份验证支持两种认证方式
1. **请求头认证**(推荐):
- `Authorization: Bearer <token>`
-`X-Authorization: <token>`
2. **查询参数认证**
- `?token=<token>`
认证端点:
- **POST /api/auth/login**用户登录获取JWT令牌
- **GET /api/user/info**:获取当前用户信息
成功登录后系统返回包含JWT令牌的响应后续请求需在请求头中携带该令牌。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant AuthController as "认证控制器"
participant UserService as "用户服务"
Client->>AuthController : POST /api/auth/login
AuthController->>UserService : 验证用户凭证
UserService-->>AuthController : 验证结果
AuthController->>AuthController : 生成JWT令牌
AuthController-->>Client : 返回LoginResponse包含token
Client->>Client : 存储token用于后续请求
```
**Diagram sources**
- [SecurityConfiguration.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/SecurityConfiguration.java#L40-L70)
- [LoginResponse.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/LoginResponse.java)
### 设备管理接口
#### 充电站管理
提供对充电站的CRUD操作和查询功能。
| HTTP方法 | URL路径 | 描述 |
|--------|-----------------------|-------------------|
| GET | /api/stations | 分页查询充电站列表 |
| GET | /api/stations/{id} | 根据ID获取充电站详情 |
| POST | /api/stations | 创建新的充电站 |
| PUT | /api/stations/{id} | 更新充电站信息 |
| DELETE | /api/stations/{id} | 删除充电站 |
| GET | /api/stations/options | 获取充电站选项列表(用于下拉选择) |
| GET | /api/stations/search | 搜索充电站选项(支持关键字) |
**请求体 (POST /api/stations) - StationCreateRequest:**
```json
{
"stationName": "string, 充电站名称, 必填",
"stationCode": "string, 充电站编码, 必填",
"longitude": "number, 经度",
"latitude": "number, 纬度",
"province": "string, 省份",
"city": "string, 城市",
"county": "string, 区县",
"address": "string, 详细地址"
}
```
**响应体:**
```json
{
"success": true,
"message": "创建成功",
"data": {
"id": "uuid, 充电站ID",
"stationName": "string, 充电站名称",
"stationCode": "string, 充电站编码",
"longitude": "number, 经度",
"latitude": "number, 纬度",
"province": "string, 省份",
"city": "string, 城市",
"county": "string, 区县",
"address": "string, 详细地址",
"createdTime": "datetime, 创建时间"
},
"timestamp": "number, 时间戳"
}
```
**curl示例:**
```bash
curl -X POST "http://localhost:8080/api/stations" \
-H "Authorization: Bearer your-jwt-token" \
-H "Content-Type: application/json" \
-d '{
"stationName": "高新科技园充电站",
"stationCode": "ST001",
"longitude": 113.944,
"latitude": 22.543,
"province": "广东省",
"city": "深圳市",
"county": "南山区",
"address": "科技园南区1号"
}'
```
#### 充电桩管理
提供对充电桩的管理功能。
| HTTP方法 | URL路径 | 描述 |
|--------|------------------------------|-----------------|
| POST | /api/piles | 创建新的充电桩 |
| GET | /api/piles/{id} | 根据ID获取充电桩详情 |
| PUT | /api/piles/{id} | 更新充电桩信息 |
| DELETE | /api/piles/{id} | 删除充电桩 |
| GET | /api/piles | 分页查询充电桩列表(包含状态) |
| GET | /api/piles/options | 获取充电桩选项列表 |
| GET | /api/piles/status/{pileCode} | 根据桩编号获取充电桩状态 |
**curl示例:**
```bash
curl -X GET "http://localhost:8080/api/piles/status/P001" \
-H "Authorization: Bearer your-jwt-token"
```
#### 充电枪管理
提供对充电枪的管理功能。
| HTTP方法 | URL路径 | 描述 |
|--------|----------------------------|-----------------|
| POST | /api/guns | 创建新的充电枪 |
| GET | /api/guns/{id} | 根据ID获取充电枪详情 |
| PUT | /api/guns/{id} | 更新充电枪信息 |
| DELETE | /api/guns/{id} | 删除充电枪 |
| GET | /api/guns | 分页查询充电枪列表(包含状态) |
| GET | /api/guns/status/{gunCode} | 根据枪编号获取充电枪运行状态 |
| GET | /api/guns/code/{gunCode} | 根据充电枪编码获取详细信息 |
**curl示例:**
```bash
curl -X GET "http://localhost:8080/api/guns/code/G001" \
-H "Authorization: Bearer your-jwt-token"
```
**Section sources**
- [StationController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/StationController.java)
- [PileController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/PileController.java)
- [GunController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/GunController.java)
- [StationCreateRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/StationCreateRequest.java)
### 协议管理接口
提供协议相关的查询功能。
| HTTP方法 | URL路径 | 描述 |
|--------|--------------------------|-------------|
| GET | /api/protocols/supported | 获取所有支持的协议列表 |
**响应体:**
```json
{
"success": true,
"message": "查询成功",
"data": [
{
"value": "string, 协议标识符",
"label": "string, 显示名称"
}
],
"timestamp": "number, 时间戳"
}
```
**curl示例:**
```bash
curl -X GET "http://localhost:8080/api/protocols/supported" \
-H "Authorization: Bearer your-jwt-token"
```
**Section sources**
- [ProtocolController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/ProtocolController.java)
### RPC接口
提供通用化的充电桩远程过程调用接口,支持多种控制命令。
| HTTP方法 | URL路径 | 描述 |
|--------|------------------------|-------------------|
| POST | /api/rpc/oneway | 单向RPC调用不等待响应 |
| POST | /api/rpc/bidirectional | 双向RPC调用等待响应待实现 |
**请求体 - RpcRequest:**
```json
{
"method": "string, RPC方法名, 必填",
"parameter": "object, 方法参数, JSON格式, 必填",
"timeoutMs": "number, 超时时间毫秒仅用于双向RPC"
}
```
支持的`method`值:
- `startCharge`: 启动充电
- `stopCharge`: 停止充电
- `restartPile`: 重启充电桩
- `setPricing`: 设置计费策略
- `setQrcode`: 设置二维码
- `otaRequest`: OTA升级
- `offlineCardBalanceUpdate`: 离线卡余额更新
- `offlineCardSync`: 离线卡同步
- `offlineCardClear`: 离线卡清除
- `offlineCardQuery`: 离线卡查询
- `timeSync`: 时间同步
#### 启动充电
**method**: `startCharge`
**parameter结构 - StartChargeDTO:**
```json
{
"pileCode": "string, 充电桩编码, 必填",
"gunNo": "string, 充电枪编号, 必填",
"limitYuan": "number, 限制金额(元), 必填",
"orderNo": "string, 订单号, 必填",
"logicalCardNo": "string, 逻辑卡号",
"physicalCardNo": "string, 物理卡号",
"parallelNo": "string, 并充序号"
}
```
**curl示例:**
```bash
curl -X POST "http://localhost:8080/api/rpc/oneway" \
-H "Authorization: Bearer your-jwt-token" \
-H "Content-Type: application/json" \
-d '{
"method": "startCharge",
"parameter": {
"pileCode": "P001",
"gunNo": "G001",
"limitYuan": 100.00,
"orderNo": "ORD20240101001",
"logicalCardNo": "LC001",
"physicalCardNo": "PC001"
}
}'
```
#### 停止充电
**method**: `stopCharge`
**parameter结构 - StopChargeDTO:**
```json
{
"pileCode": "string, 充电桩编码, 必填",
"gunNo": "string, 充电枪编号, 必填"
}
```
**curl示例:**
```bash
curl -X POST "http://localhost:8080/api/rpc/oneway" \
-H "Authorization: Bearer your-jwt-token" \
-H "Content-Type: application/json" \
-d '{
"method": "stopCharge",
"parameter": {
"pileCode": "P001",
"gunNo": "G001"
}
}'
```
**Section sources**
- [RpcController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/RpcController.java)
- [StartChargeDTO.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/dto/StartChargeDTO.java)
- [StopChargeDTO.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/dto/StopChargeDTO.java)
- [RpcRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/RpcRequest.java)
## gRPC接口
系统提供gRPC接口用于高效的双向通信主要服务于DownlinkGrpcService。
### 服务定义
`grpc.proto`文件中定义了`ProtocolInterface`服务:
```protobuf
service ProtocolInterface {
rpc onDownlink(stream RequestMsg) returns (stream ResponseMsg) {}
}
```
### 消息类型
#### RequestMsg
```protobuf
message RequestMsg {
int64 ts = 1;
TracerProto tracer = 2;
ConnectRequestMsg connectRequestMsg = 10;
DownlinkRequestMessage downlinkRequestMessage = 11;
}
```
#### ResponseMsg
```protobuf
message ResponseMsg {
TracerProto tracer = 2;
ConnectResponseMsg connectResponseMsg = 12;
DownlinkResponseMessage downlinkResponseMsg = 13;
}
```
### 连接流程
1. 客户端建立gRPC连接到服务器
2. 发送包含`ConnectRequestMsg``RequestMsg`
3. 服务器返回包含`ConnectResponseMsg``ResponseMsg`
4. 连接建立成功后,可发送`DownlinkRequestMessage`进行下行指令
### DownlinkRequestMessage
定义在`downlink.proto`中,包含各种充电桩控制指令。
### Java客户端调用示例
```java
// 创建gRPC通道
ManagedChannel channel = ManagedChannelBuilder
.forAddress("localhost", 6001)
.usePlaintext()
.build();
// 创建Stub
ProtocolInterfaceGrpc.ProtocolInterfaceStub stub =
ProtocolInterfaceGrpc.newStub(channel);
// 创建流观察者
StreamObserver<RequestMsg> requestObserver = stub.onDownlink(
new StreamObserver<ResponseMsg>() {
@Override
public void onNext(ResponseMsg response) {
// 处理服务器响应
System.out.println("收到响应: " + response);
}
@Override
public void onError(Throwable t) {
// 处理错误
System.err.println("gRPC错误: " + t.getMessage());
}
@Override
public void onCompleted() {
// 流完成
System.out.println("连接关闭");
}
}
);
// 发送连接请求
requestObserver.onNext(
RequestMsg.newBuilder()
.setConnectRequestMsg(
ConnectRequestMsg.newBuilder()
.setNodeId("client-001")
.build()
)
.build()
);
// 发送下行指令
UUID sessionId = UUID.randomUUID();
requestObserver.onNext(
RequestMsg.newBuilder()
.setDownlinkRequestMessage(
DownlinkRequestMessage.newBuilder()
.setSessionIdMSB(sessionId.getMostSignificantBits())
.setSessionIdLSB(sessionId.getLeastSignificantBits())
// 设置具体指令内容
.build()
)
.build()
);
```
**Diagram sources**
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java)
- [grpc.proto](file://jcpp-infrastructure-proto/src/main/proto/grpc.proto)
- [downlink.proto](file://jcpp-infrastructure-proto/src/main/proto/downlink.proto)
## 通用响应结构
所有RESTful API响应均采用统一的`ApiResponse`结构:
```json
{
"success": "boolean, 操作是否成功",
"errorCode": "string, 错误码(失败时存在)",
"message": "string, 响应消息",
"data": "object, 响应数据(成功时存在)",
"timestamp": "number, 时间戳"
}
```
**Section sources**
- [ApiResponse.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/ApiResponse.java)
## 错误码体系
系统定义了统一的错误码体系`JCPPErrorCode`,用于标准化错误响应。
| 错误码 | HTTP状态码 | 描述 |
|-----|---------|---------|
| 2 | 500 | 通用错误 |
| 10 | 401 | 认证失败 |
| 11 | 401 | JWT令牌过期 |
| 15 | 401 | 凭证过期 |
| 20 | 403 | 权限拒绝 |
| 30 | 400 | 无效参数 |
| 31 | 400 | 请求参数错误 |
| 32 | 404 | 项目未找到 |
| 33 | 429 | 请求过多 |
| 34 | 429 | 更新过多 |
| 35 | 409 | 版本冲突 |
| 40 | 403 | 订阅违规 |
| 45 | 401 | 密码违规 |
| 46 | 500 | 数据库错误 |
错误响应示例:
```json
{
"success": false,
"errorCode": "AUTHENTICATION",
"message": "认证失败",
"timestamp": 1700000000000
}
```
**Section sources**
- [JCPPErrorCode.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/exception/JCPPErrorCode.java)
- [JCPPErrorResponseHandler.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/exception/JCPPErrorResponseHandler.java)
## 速率限制
系统实现了速率限制机制防止API被滥用。速率限制通过`@RateLimit`注解实现,配置在需要限制的接口上。
当请求超过限制时,系统返回`429 Too Many Requests`状态码,错误码为`TOO_MANY_REQUESTS`33
**Section sources**
- [RateLimit.java](file://jcpp-infrastructure-util/src/main/java/sanbing/jcpp/infrastructure/util/validation/RateLimit.java)

View File

@@ -0,0 +1,636 @@
# REST API
<cite>
**本文档引用的文件**
- [UserController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/UserController.java)
- [StationController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/StationController.java)
- [PileController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/PileController.java)
- [GunController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/GunController.java)
- [ProtocolController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/ProtocolController.java)
- [RpcController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/RpcController.java)
- [BaseController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/BaseController.java)
- [ApiResponse.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/ApiResponse.java)
- [LoginResponse.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/LoginResponse.java)
- [ErrorCode.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/ErrorCode.java)
- [JCPPErrorCode.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/exception/JCPPErrorCode.java)
- [PageRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/PageRequest.java)
- [StationCreateRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/StationCreateRequest.java)
- [PileCreateRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/PileCreateRequest.java)
- [GunCreateRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/GunCreateRequest.java)
- [RpcRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/RpcRequest.java)
- [StartChargeDTO.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/dto/StartChargeDTO.java)
- [SecurityConfiguration.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/SecurityConfiguration.java)
- [JCPPErrorResponseHandler.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/exception/JCPPErrorResponseHandler.java)
</cite>
## 目录
1. [简介](#简介)
2. [认证机制](#认证机制)
3. [通用响应格式](#通用响应格式)
4. [分页查询参数](#分页查询参数)
5. [全局异常处理](#全局异常处理)
6. [错误码列表](#错误码列表)
7. [用户认证API](#用户认证api)
8. [设备管理API](#设备管理api)
9. [协议交互API](#协议交互api)
10. [远程过程调用API](#远程过程调用api)
11. [curl命令示例](#curl命令示例)
## 简介
本文档为JChargePointProtocol系统提供全面的REST API文档涵盖用户认证、设备管理、协议交互和远程过程调用等核心功能。所有API端点均采用统一的响应格式和错误处理机制确保接口的一致性和易用性。
**本文档引用的文件**
- [StationController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/StationController.java)
- [PileController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/PileController.java)
- [GunController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/GunController.java)
- [ProtocolController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/ProtocolController.java)
- [RpcController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/RpcController.java)
## 认证机制
系统采用JWTJSON Web Token进行身份认证和授权。客户端在成功登录后会获得一个JWT令牌后续请求需要在请求头中携带该令牌。
### 认证方式
支持以下两种方式传递JWT令牌
1. **Authorization请求头**(推荐)
```
Authorization: Bearer <JWT_TOKEN>
```
2. **自定义请求头**
```
X-Authorization: <JWT_TOKEN>
```
### 认证流程
1. 用户通过`/api/auth/login`端点进行登录,提供用户名和密码
2. 服务器验证凭据成功后返回包含JWT令牌的响应
3. 客户端在后续所有请求的请求头中包含JWT令牌
4. 服务器验证令牌的有效性,决定是否授予访问权限
令牌过期后,客户端需要使用刷新令牌获取新的访问令牌。
**本文档引用的文件**
- [SecurityConfiguration.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/SecurityConfiguration.java)
- [LoginResponse.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/LoginResponse.java)
## 通用响应格式
所有API响应均采用统一的`ApiResponse`格式,确保客户端能够一致地处理成功和错误响应。
### 响应结构
```json
{
"success": true,
"errorCode": "SUCCESS",
"message": "操作成功",
"data": {},
"timestamp": 1700000000000
}
```
### 字段说明
- **success**: 布尔值,表示请求是否成功
- **errorCode**: 错误码,成功时为"SUCCESS",失败时为具体的错误码
- **message**: 响应消息,描述操作结果
- **data**: 响应数据,包含实际的业务数据
- **timestamp**: 时间戳,记录响应生成的时间
### 成功响应示例
```json
{
"success": true,
"errorCode": "SUCCESS",
"message": "查询成功",
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"stationName": "测试充电站",
"stationCode": "ST001"
},
"timestamp": 1700000000000
}
```
### 错误响应示例
```json
{
"success": false,
"errorCode": "UNAUTHORIZED",
"message": "用户未认证",
"timestamp": 1700000000000
}
```
**本文档引用的文件**
- [ApiResponse.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/ApiResponse.java)
## 分页查询参数
大多数查询接口支持分页功能,通过`PageRequest`类定义分页参数。
### 分页参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|-----------|---------|----|------|-----------------------|
| page | Integer | 否 | 1 | 页码从1开始 |
| size | Integer | 否 | 10 | 每页大小 |
| sortField | String | 否 | - | 排序字段 |
| sortOrder | String | 否 | desc | 排序方向asc(升序)或desc(降序) |
| search | String | 否 | - | 搜索关键词 |
### 示例
获取第2页的充电站列表每页20条记录按创建时间降序排列
```
GET /api/stations?page=2&size=20&sortField=createTime&sortOrder=desc
```
**本文档引用的文件**
- [PageRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/PageRequest.java)
## 全局异常处理
系统通过`BaseController`类提供统一的异常处理机制,确保所有异常都能被妥善处理并返回标准化的错误响应。
### 异常处理流程
1. 捕获控制器中的各种异常
2. 将异常转换为`JCPPException`
3. 通过`JCPPErrorResponseHandler`生成标准化的错误响应
4. 返回给客户端
### 支持的异常类型
- `Exception`: 通用异常
- `JCPPException`: JCPP自定义异常
- `MethodArgumentNotValidException`: 参数校验异常
**本文档引用的文件**
- [BaseController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/BaseController.java)
- [JCPPErrorResponseHandler.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/exception/JCPPErrorResponseHandler.java)
## 错误码列表
系统定义了统一的错误码体系,便于客户端识别和处理不同类型的错误。
### 通用错误码
| 错误码 | 说明 |
|------------------|------------|
| SUCCESS | 操作成功 |
| SYSTEM_ERROR | 系统异常,请稍后重试 |
| BUSINESS_ERROR | 业务处理失败 |
| VALIDATION_ERROR | 参数校验失败 |
| BINDING_ERROR | 数据绑定异常 |
| ILLEGAL_ARGUMENT | 参数错误 |
| ILLEGAL_STATE | 状态错误 |
### 认证授权相关
| 错误码 | 说明 |
|-----------------|---------------|
| UNAUTHORIZED | 用户未认证 |
| AUTH_FAILED | 用户名或密码错误 |
| JWT_AUTH_FAILED | JWT Token认证失败 |
| FORBIDDEN | 权限不足 |
### 资源相关
| 错误码 | 说明 |
|-----------|----------|
| NOT_FOUND | 请求的资源不存在 |
| CONFLICT | 资源冲突 |
### 业务特定错误码
| 错误码 | 说明 |
|---------------------|----------|
| PILE_CODE_EXISTS | 充电桩编码已存在 |
| STATION_NAME_EXISTS | 充电站名称已存在 |
| GUN_CODE_EXISTS | 充电枪编号已存在 |
| PILE_NOT_FOUND | 充电桩不存在 |
| STATION_NOT_FOUND | 充电站不存在 |
| GUN_NOT_FOUND | 充电枪不存在 |
**本文档引用的文件**
- [ErrorCode.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/ErrorCode.java)
- [JCPPErrorCode.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/exception/JCPPErrorCode.java)
## 用户认证API
提供用户登录和获取用户信息的接口。
### 登录
- **HTTP方法**: POST
- **URL路径**: `/api/auth/login`
- **请求头**: 无特殊要求
- **请求体**:
```json
{
"username": "string",
"password": "string"
}
```
- **响应体**:
```json
{
"success": true,
"errorCode": "SUCCESS",
"message": "操作成功",
"data": {
"token": "string",
"refreshToken": "string",
"tokenType": "Bearer",
"user": {
"id": "string",
"username": "string",
"status": "ENABLE"
}
},
"timestamp": 1700000000000
}
```
### 获取用户信息
- **HTTP方法**: GET
- **URL路径**: `/api/user/info`
- **请求头**: `Authorization: Bearer <JWT>`
- **响应体**:
```json
{
"success": true,
"errorCode": "SUCCESS",
"message": "操作成功",
"data": {
"id": "string",
"username": "string",
"status": "ENABLE"
},
"timestamp": 1700000000000
}
```
**本文档引用的文件**
- [UserController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/UserController.java)
- [LoginResponse.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/response/LoginResponse.java)
## 设备管理API
提供对充电站、充电桩和充电枪的增删改查操作。
### 充电站管理
#### 查询充电站列表
- **HTTP方法**: GET
- **URL路径**: `/api/stations`
- **请求头**: `Authorization: Bearer <JWT>`
- **查询参数**: 继承自`PageRequest`
- **响应体**:
```json
{
"success": true,
"errorCode": "SUCCESS",
"message": "查询成功",
"data": {
"content": [
{
"id": "uuid",
"stationName": "string",
"stationCode": "string",
"longitude": 120.123,
"latitude": 30.456,
"province": "string",
"city": "string",
"county": "string",
"address": "string"
}
],
"totalElements": 1,
"totalPages": 1,
"page": 1,
"size": 10
},
"timestamp": 1700000000000
}
```
#### 创建充电站
- **HTTP方法**: POST
- **URL路径**: `/api/stations`
- **请求头**: `Authorization: Bearer <JWT>`
- **请求体**: `StationCreateRequest`
```json
{
"stationName": "string",
"stationCode": "string",
"longitude": 120.123,
"latitude": 30.456,
"province": "string",
"city": "string",
"county": "string",
"address": "string"
}
```
- **字段说明**:
- stationName: 充电站名称,必填,不能为空
- stationCode: 充电站编码,必填,不能为空
- longitude: 经度,浮点数
- latitude: 纬度,浮点数
- province: 省份
- city: 城市
- county: 区县
- address: 详细地址
**本文档引用的文件**
- [StationController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/StationController.java)
- [StationCreateRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/StationCreateRequest.java)
#### 更新充电站
- **HTTP方法**: PUT
- **URL路径**: `/api/stations/{id}`
- **请求头**: `Authorization: Bearer <JWT>`
- **路径参数**: id - 充电站ID (UUID)
- **请求体**: `StationUpdateRequest`
```json
{
"stationName": "string",
"longitude": 120.123,
"latitude": 30.456,
"province": "string",
"city": "string",
"county": "string",
"address": "string"
}
```
#### 删除充电站
- **HTTP方法**: DELETE
- **URL路径**: `/api/stations/{id}`
- **请求头**: `Authorization: Bearer <JWT>`
- **路径参数**: id - 充电站ID (UUID)
### 充电桩管理
#### 创建充电桩
- **HTTP方法**: POST
- **URL路径**: `/api/piles`
- **请求头**: `Authorization: Bearer <JWT>`
- **请求体**: `PileCreateRequest`
```json
{
"pileName": "string",
"pileCode": "string",
"protocol": "string",
"stationId": "uuid",
"brand": "string",
"model": "string",
"manufacturer": "string",
"type": "DC"
}
```
- **字段说明**:
- pileName: 充电桩名称,必填,不能为空
- pileCode: 充电桩编码,必填,不能为空
- protocol: 协议,必填,不能为空
- stationId: 所属充电站ID必填不能为空
- brand: 品牌
- model: 型号
- manufacturer: 制造商
- type: 类型默认为DC直流
**本文档引用的文件**
- [PileController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/PileController.java)
- [PileCreateRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/PileCreateRequest.java)
#### 查询充电桩列表
- **HTTP方法**: GET
- **URL路径**: `/api/piles`
- **请求头**: `Authorization: Bearer <JWT>`
- **查询参数**: 继承自`PageRequest`
- **响应体**:
```json
{
"success": true,
"errorCode": "SUCCESS",
"message": "查询成功",
"data": {
"content": [
{
"id": "uuid",
"pileName": "string",
"pileCode": "string",
"protocol": "string",
"stationId": "uuid",
"brand": "string",
"model": "string",
"manufacturer": "string",
"type": "DC",
"status": "string"
}
],
"totalElements": 1,
"totalPages": 1,
"page": 1,
"size": 10
},
"timestamp": 1700000000000
}
```
### 充电枪管理
#### 创建充电枪
- **HTTP方法**: POST
- **URL路径**: `/api/guns`
- **请求头**: `Authorization: Bearer <JWT>`
- **请求体**: `GunCreateRequest`
```json
{
"gunName": "string",
"gunNo": "string",
"gunCode": "string",
"stationId": "uuid",
"pileId": "uuid"
}
```
- **字段说明**:
- gunName: 充电枪名称,必填,不能为空
- gunNo: 充电枪编号,必填,不能为空
- gunCode: 充电枪编码,必填,不能为空
- stationId: 所属充电站ID必填不能为空
- pileId: 所属充电桩ID必填不能为空
**本文档引用的文件**
- [GunController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/GunController.java)
- [GunCreateRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/GunCreateRequest.java)
## 协议交互API
提供协议相关的查询接口。
### 获取支持的协议列表
- **HTTP方法**: GET
- **URL路径**: `/api/protocols/supported`
- **请求头**: `Authorization: Bearer <JWT>`
- **响应体**:
```json
{
"success": true,
"errorCode": "SUCCESS",
"message": "查询成功",
"data": [
{
"value": "LVNENG_V340",
"label": "绿能V3.4.0"
},
{
"value": "YUNKUAICHONG_V150",
"label": "云快充V1.5.0"
}
],
"timestamp": 1700000000000
}
```
**本文档引用的文件**
- [ProtocolController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/ProtocolController.java)
## 远程过程调用API
提供通用化的充电桩下行指令接口。
### 单向RPC
- **HTTP方法**: POST
- **URL路径**: `/api/rpc/oneway`
- **请求头**: `Authorization: Bearer <JWT>`
- **请求体**: `RpcRequest`
```json
{
"method": "string",
"parameter": {},
"timeoutMs": 10000
}
```
- **字段说明**:
- method: RPC方法名必填不能为空
- parameter: 方法参数JSON格式必填不能为空
- timeoutMs: 超时时间毫秒仅用于双向RPC
**本文档引用的文件**
- [RpcController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/RpcController.java)
- [RpcRequest.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/request/RpcRequest.java)
#### 支持的方法
| 方法名 | 说明 | 参数结构 |
|--------------------------|---------|-----------------------------------|
| startCharge | 启动充电 | `StartChargeDTO` |
| stopCharge | 停止充电 | `StopChargeDTO` |
| restartPile | 重启充电桩 | `RestartPileDTO` |
| setPricing | 设置计费策略 | `SetPricingDTO` |
| setQrcode | 设置二维码 | `SetQrcodeRequest` |
| otaRequest | OTA升级 | `OtaRequest` |
| offlineCardBalanceUpdate | 离线卡余额更新 | `OfflineCardBalanceUpdateRequest` |
| offlineCardSync | 离线卡同步 | `OfflineCardSyncRequest` |
| offlineCardClear | 离线卡清除 | `OfflineCardClearRequest` |
| offlineCardQuery | 离线卡查询 | `OfflineCardQueryRequest` |
| timeSync | 时间同步 | `TimeSyncDTO` |
### 启动充电示例
```json
{
"method": "startCharge",
"parameter": {
"pileCode": "P001",
"gunNo": "G01",
"limitYuan": 100.00,
"orderNo": "ORDER_001",
"logicalCardNo": "LOGICAL_001",
"physicalCardNo": "PHYSICAL_001",
"parallelNo": "PARALLEL_001"
}
}
```
**本文档引用的文件**
- [StartChargeDTO.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/dto/StartChargeDTO.java)
## curl命令示例
以下是一些常用的curl命令示例演示如何使用API。
### 登录
```bash
curl -X POST "http://localhost:8080/api/auth/login" \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "password"
}'
```
### 查询电站列表
```bash
curl -X GET "http://localhost:8080/api/stations?page=1&size=10" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```
### 下发启动充电指令
```bash
curl -X POST "http://localhost:8080/api/rpc/oneway" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"method": "startCharge",
"parameter": {
"pileCode": "P001",
"gunNo": "G01",
"limitYuan": 100.00,
"orderNo": "ORDER_001"
}
}'
```
**本文档引用的文件**
- [UserController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/UserController.java)
- [StationController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/StationController.java)
- [RpcController.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/adapter/controller/RpcController.java)

View File

@@ -0,0 +1,826 @@
# JChargePointProtocol gRPC API 文档
<cite>
**本文档引用的文件**
- [downlink.proto](file://jcpp-infrastructure-proto/src/main/proto/downlink.proto)
- [grpc.proto](file://jcpp-infrastructure-proto/src/main/proto/grpc.proto)
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java)
- [DownlinkGrpcClient.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/grpc/DownlinkGrpcClient.java)
- [ProtoConverter.java](file://jcpp-infrastructure-proto/src/main/java/sanbing/jcpp/infrastructure/proto/ProtoConverter.java)
- [GrpcDownlinkCallService.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/impl/GrpcDownlinkCallService.java)
- [protocol-service.yml](file://jcpp-protocol-bootstrap/src/main/resources/protocol-service.yml)
- [app-service.yml](file://jcpp-app-bootstrap/src/main/resources/app-service.yml)
</cite>
## 目录
1. [简介](#简介)
2. [项目架构概览](#项目架构概览)
3. [gRPC服务定义](#grpc服务定义)
4. [消息类型详解](#消息类型详解)
5. [Protobuf序列化机制](#protobuf序列化机制)
6. [ProtoConverter转换器](#protoconverter转换器)
7. [gRPC客户端实现](#grpc客户端实现)
8. [服务端点实现](#服务端点实现)
9. [错误处理机制](#错误处理机制)
10. [性能优化配置](#性能优化配置)
11. [适用场景对比](#适用场景对比)
12. [最佳实践指南](#最佳实践指南)
## 简介
JChargePointProtocol是一个基于gRPC的充电桩通信协议系统专门设计用于电动汽车充电站的高效通信。该系统采用Protocol
Buffers作为序列化机制提供了高性能、低延迟的双向流式通信能力。
### 核心特性
- **高性能通信**基于gRPC和Protocol Buffers的高效序列化
- **双向流式通信**:支持实时数据传输和状态同步
- **可扩展架构**:模块化的服务设计,便于功能扩展
- **强类型安全**:编译时类型检查,减少运行时错误
- **跨语言兼容**:支持多种编程语言的客户端开发
## 项目架构概览
```mermaid
graph TB
subgraph "客户端层"
APP[应用程序]
CLIENT[gRPC客户端]
end
subgraph "网络层"
GATEWAY[网关/负载均衡器]
LB[负载均衡策略]
end
subgraph "服务端层"
SERVER[gRPC服务端]
SESSION[会话管理]
PROTO[协议处理器]
end
subgraph "存储层"
CACHE[缓存系统]
DB[(数据库)]
end
APP --> CLIENT
CLIENT --> GATEWAY
GATEWAY --> LB
LB --> SERVER
SERVER --> SESSION
SESSION --> PROTO
PROTO --> CACHE
PROTO --> DB
```
**图表来源**
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L42-L184)
- [DownlinkGrpcClient.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/grpc/DownlinkGrpcClient.java#L33-L297)
## gRPC服务定义
### ProtocolInterface服务
系统的核心gRPC服务定义在`grpc.proto`文件中,提供了统一的通信接口。
```mermaid
classDiagram
class ProtocolInterface {
<<service>>
+onDownlink(stream RequestMsg) stream ResponseMsg
}
class RequestMsg {
+int64 ts
+TracerProto tracer
+ConnectRequestMsg connectRequestMsg
+DownlinkRequestMessage downlinkRequestMessage
}
class ResponseMsg {
+TracerProto tracer
+ConnectResponseMsg connectResponseMsg
+DownlinkResponseMessage downlinkResponseMsg
}
class ConnectRequestMsg {
+string nodeId
}
class ConnectResponseMsg {
+ConnectResponseCode responseCode
+string errorMsg
}
class TracerProto {
+string id
+string origin
+int64 ts
}
ProtocolInterface --> RequestMsg : "接收"
ProtocolInterface --> ResponseMsg : "返回"
RequestMsg --> ConnectRequestMsg : "包含"
RequestMsg --> DownlinkRequestMessage : "包含"
ResponseMsg --> ConnectResponseMsg : "包含"
ResponseMsg --> DownlinkResponseMessage : "包含"
RequestMsg --> TracerProto : "追踪"
ResponseMsg --> TracerProto : "追踪"
```
**图表来源**
- [grpc.proto](file://jcpp-infrastructure-proto/src/main/proto/grpc.proto#L13-L57)
### 核心RPC方法
#### onDownlink方法
这是系统的主要RPC方法实现了双向流式通信
| 参数类型 | 名称 | 描述 |
|--------------------|----------|------------------|
| stream RequestMsg | request | 流式请求消息,支持持续的数据传输 |
| stream ResponseMsg | response | 流式响应消息,实时返回处理结果 |
**节来源**
- [grpc.proto](file://jcpp-infrastructure-proto/src/main/proto/grpc.proto#L13-L14)
## 消息类型详解
### RequestMsg请求消息
RequestMsg是gRPC通信的入口消息包含了完整的上下文信息。
| 字段 | 类型 | 标签 | 描述 |
|------------------------|------------------------|----|-----------------|
| ts | int64 | 必需 | 时间戳,用于消息排序和过期检测 |
| tracer | TracerProto | 可选 | 追踪信息,支持分布式链路追踪 |
| connectRequestMsg | ConnectRequestMsg | 可选 | 连接请求消息 |
| downlinkRequestMessage | DownlinkRequestMessage | 可选 | 下行请求消息 |
### ResponseMsg响应消息
ResponseMsg是服务端对请求的响应消息。
| 字段 | 类型 | 标签 | 描述 |
|---------------------|-------------------------|----|-----------------|
| tracer | TracerProto | 可选 | 追踪信息,保持请求响应的一致性 |
| connectResponseMsg | ConnectResponseMsg | 可选 | 连接响应消息 |
| downlinkResponseMsg | DownlinkResponseMessage | 可选 | 下行响应消息 |
### ConnectRequestMsg连接请求
用于建立和维护gRPC连接。
| 字段 | 类型 | 标签 | 描述 |
|--------|--------|----|---------|
| nodeId | string | 必需 | 节点唯一标识符 |
### ConnectResponseMsg连接响应
连接建立后的确认消息。
| 字段 | 类型 | 标签 | 描述 |
|--------------|---------------------|----|-----------------------|
| responseCode | ConnectResponseCode | 必需 | 连接状态码ACCEPTED或REFUSE |
| errorMsg | string | 可选 | 错误信息(仅在连接被拒绝时提供) |
### DownlinkRequestMessage下行请求
这是最复杂的消息类型,包含了各种充电桩操作指令。
| 字段 | 类型 | 标签 | 描述 |
|---------------------------------|---------------------------------|----|-----------|
| messageIdMSB | int64 | 必需 | 消息ID高64位 |
| messageIdLSB | int64 | 必需 | 消息ID低64位 |
| sessionIdMSB | int64 | 必需 | 会话ID高64位 |
| sessionIdLSB | int64 | 必需 | 会话ID低64位 |
| protocolName | string | 必需 | 协议名称 |
| pileCode | string | 必需 | 充电桩编码 |
| requestIdMSB | int64 | 可选 | 请求ID高64位 |
| requestIdLSB | int64 | 可选 | 请求ID低64位 |
| requestData | bytes | 可选 | 原始请求数据 |
| downlinkCmd | string | 必需 | 下行命令类型 |
| LoginResponse | LoginResponse | 可选 | 登录响应 |
| VerifyPricingResponse | VerifyPricingResponse | 可选 | 计费校验响应 |
| QueryPricingResponse | QueryPricingResponse | 可选 | 计费查询响应 |
| SetPricingRequest | SetPricingRequest | 可选 | 设置计费请求 |
| RemoteStartChargingRequest | RemoteStartChargingRequest | 可选 | 远程启动充电请求 |
| RemoteStopChargingRequest | RemoteStopChargingRequest | 可选 | 远程停止充电请求 |
| TransactionRecordResponse | TransactionRecordResponse | 可选 | 交易记录响应 |
| RestartPileRequest | RestartPileRequest | 可选 | 重启充电桩请求 |
| OtaRequest | OtaRequest | 可选 | OTA升级请求 |
| OfflineCardBalanceUpdateRequest | OfflineCardBalanceUpdateRequest | 可选 | 离线卡余额更新请求 |
| OfflineCardSyncRequest | OfflineCardSyncRequest | 可选 | 离线卡同步请求 |
| TimeSyncRequest | TimeSyncRequest | 可选 | 时间同步请求 |
| StartChargeResponse | StartChargeResponse | 可选 | 启动充电响应 |
| SetQrcodeRequest | SetQrcodeRequest | 可选 | 设置二维码请求 |
| OfflineCardClearRequest | OfflineCardClearRequest | 可选 | 离线卡清除请求 |
| OfflineCardQueryRequest | OfflineCardQueryRequest | 可选 | 离线卡查询请求 |
| WorkParamSettingRequest | WorkParamSettingRequest | 可选 | 工作参数设置请求 |
**节来源**
- [grpc.proto](file://jcpp-infrastructure-proto/src/main/proto/grpc.proto#L15-L57)
- [downlink.proto](file://jcpp-infrastructure-proto/src/main/proto/downlink.proto#L10-L282)
## Protobuf序列化机制
### 序列化优势
Protocol Buffers提供了以下核心优势
1. **紧凑的二进制格式**相比JSON等文本格式体积更小传输更快
2. **向前向后兼容**:新版本可以读取旧版本数据,反之亦然
3. **类型安全**:编译时检查,避免运行时类型错误
4. **多语言支持**:自动生成多种语言的代码
### 序列化流程
```mermaid
flowchart TD
JAVA_OBJ["Java对象"] --> CONVERTER["ProtoConverter"]
CONVERTER --> PROTO_MSG["Protobuf消息"]
PROTO_MSG --> SERIALIZATION["序列化"]
SERIALIZATION --> NETWORK["网络传输"]
NETWORK --> DESERIALIZATION["反序列化"]
DESERIALIZATION --> PROTO_MSG_REV["Protobuf消息"]
PROTO_MSG_REV --> CONVERTER_REV["ProtoConverter"]
CONVERTER_REV --> JAVA_OBJ_REV["Java对象"]
```
**图表来源**
- [ProtoConverter.java](file://jcpp-infrastructure-proto/src/main/java/sanbing/jcpp/infrastructure/proto/ProtoConverter.java#L20-L141)
### 数据类型映射
| Protobuf类型 | Java类型 | 描述 |
|------------|---------|----------|
| int32 | int | 32位整数 |
| int64 | long | 64位整数 |
| string | String | UTF-8字符串 |
| bytes | byte[] | 字节数组 |
| bool | boolean | 布尔值 |
| enum | Enum | 枚举类型 |
| message | Message | 嵌套消息 |
**节来源**
- [downlink.proto](file://jcpp-infrastructure-proto/src/main/proto/downlink.proto#L1-L282)
## ProtoConverter转换器
### 转换器架构
ProtoConverter负责在Java业务对象和Protobuf消息之间进行转换确保类型安全和数据完整性。
```mermaid
classDiagram
class ProtoConverter {
<<utility>>
+toTracerProto() TracerProto
+toPricingModel(PricingModel) PricingModelProto
}
class PricingModel {
+PricingModelType type
+PricingModelRule rule
+BigDecimal standardElec
+BigDecimal standardServ
+Map~PricingModelFlag,FlagPrice~ flagPriceList
+Period[] periodsList
+TimePeriodItem[] timePeriodItems
}
class PricingModelProto {
+PricingModelType type
+PricingModelRule rule
+oneof pricing_config
}
class TracerProto {
+string id
+string origin
+int64 ts
}
ProtoConverter --> PricingModel : "转换"
ProtoConverter --> TracerProto : "创建"
PricingModel --> PricingModelProto : "转换"
```
**图表来源**
- [ProtoConverter.java](file://jcpp-infrastructure-proto/src/main/java/sanbing/jcpp/infrastructure/proto/ProtoConverter.java#L20-L141)
### 计费模型转换
ProtoConverter特别擅长处理复杂的计费模型转换支持三种计费规则
1. **标准计费**:全天统一价格
2. **峰谷计费**:按电网峰谷政策分时段
3. **时段计费**:运营商自定义时段价格
### 追踪信息转换
```java
// 追踪信息转换示例
public static TracerProto toTracerProto() {
Tracer currentTracer = TracerContextUtil.getCurrentTracer();
return TracerProto.newBuilder()
.setId(currentTracer.getTraceId())
.setOrigin(currentTracer.getOrigin())
.setTs(currentTracer.getTracerTs())
.build();
}
```
**节来源**
- [ProtoConverter.java](file://jcpp-infrastructure-proto/src/main/java/sanbing/jcpp/infrastructure/proto/ProtoConverter.java#L20-L30)
## gRPC客户端实现
### DownlinkGrpcClient架构
DownlinkGrpcClient是系统中的gRPC客户端实现负责与远程gRPC服务建立连接并发送下行请求。
```mermaid
classDiagram
class DownlinkGrpcClient {
-Map~HostAndPort,ManagedChannel~ channelMap
-Map~HostAndPort,StreamObserver~ inputStreamMap
-Map~HostAndPort,LinkedBlockingQueue~ queueMap
-Map~HostAndPort,ReentrantLock~ msgHandleLocksMap
-Map~HostAndPort,ExecutorService~ msgHandleExecutorMap
-Map~HostAndPort,AtomicInteger~ connectErrTimesMap
-Map~HostAndPort,Boolean~ initializedMap
+connect(HostAndPort) void
+sendDownlinkRequest(HostAndPort, RequestMsg) void
-handleMsgs(HostAndPort, LinkedBlockingQueue) void
}
class ManagedChannel {
+newBuilder() Builder
+shutdownNow() void
}
class StreamObserver {
+onNext(T) void
+onError(Throwable) void
+onCompleted() void
}
class RequestMsg {
+TracerProto tracer
+ConnectRequestMsg connectRequestMsg
+DownlinkRequestMessage downlinkRequestMessage
}
DownlinkGrpcClient --> ManagedChannel : "管理"
DownlinkGrpcClient --> StreamObserver : "使用"
DownlinkGrpcClient --> RequestMsg : "发送"
```
**图表来源**
- [DownlinkGrpcClient.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/grpc/DownlinkGrpcClient.java#L33-L297)
### 连接管理
客户端实现了智能的连接管理机制:
1. **自动重连**:连接断开时自动尝试重新连接
2. **连接池**:维护多个连接以提高并发能力
3. **心跳检测**:定期发送心跳保持连接活跃
4. **故障转移**:连接失败时自动切换到备用节点
### 消息队列机制
```mermaid
sequenceDiagram
participant App as 应用程序
participant Client as DownlinkGrpcClient
participant Queue as 消息队列
participant Channel as gRPC通道
participant Server as gRPC服务器
App->>Client : sendDownlinkRequest()
Client->>Queue : 添加到队列
loop 消息处理循环
Queue->>Client : 获取消息
Client->>Channel : 发送消息
Channel->>Server : onDownlink()
Server-->>Channel : 响应
Channel-->>Client : 处理响应
end
```
**图表来源**
- [DownlinkGrpcClient.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/grpc/DownlinkGrpcClient.java#L105-L185)
### 客户端配置
| 配置项 | 默认值 | 描述 |
|--------------------------|----------|---------------|
| rpcNettyEventLoop | 动态计算 | Netty事件循环线程数 |
| rpcNettySoSndbuf | 65535 | 发送缓冲区大小 |
| rpcNettySoRcvbuf | 65535 | 接收缓冲区大小 |
| rpcNoDelay | true | TCP_NODELAY选项 |
| rpcMaxInboundMessageSize | 33554432 | 最大消息大小32MB |
| keepAliveTimeSec | 300 | 心跳间隔(秒) |
| maxRecordsSize | 102400 | 最大队列大小 |
| batchRecordsCount | 1024 | 批量处理数量 |
| recordsTtl | 600000 | 消息生存时间(毫秒) |
**节来源**
- [DownlinkGrpcClient.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/grpc/DownlinkGrpcClient.java#L45-L77)
## 服务端点实现
### DownlinkGrpcService架构
DownlinkGrpcService是gRPC服务的服务器端实现继承自ProtocolInterfaceImplBase。
```mermaid
classDiagram
class DownlinkGrpcService {
-int grpcPort
-int grpcBoss
-int grpcWorker
-int grpcNettySoRcvbuf
-int grpcNettySoSndbuf
-boolean grpcNettyNoDelay
-int maxInboundMessageSize
-int maxConcurrentCallsPerConnection
-int clientMaxKeepAliveTimeSec
-Server server
-ReentrantLock replyLock
+init() void
+destroy() void
+onDownlink(StreamObserver) StreamObserver
}
class ProtocolInterfaceImplBase {
<<abstract>>
+onDownlink(StreamObserver) StreamObserver
}
class StreamObserver {
+onNext(T) void
+onError(Throwable) void
+onCompleted() void
}
class RequestMsg {
+TracerProto tracer
+ConnectRequestMsg connectRequestMsg
+DownlinkRequestMessage downlinkRequestMessage
}
class ResponseMsg {
+TracerProto tracer
+ConnectResponseMsg connectResponseMsg
+DownlinkResponseMessage downlinkResponseMsg
}
DownlinkGrpcService --|> ProtocolInterfaceImplBase
DownlinkGrpcService --> StreamObserver : "实现"
DownlinkGrpcService --> RequestMsg : "处理"
DownlinkGrpcService --> ResponseMsg : "返回"
```
**图表来源**
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L42-L184)
### 服务初始化
服务启动时会进行以下初始化步骤:
1. **配置验证**:检查必要的配置参数
2. **Netty服务器构建**配置TCP参数和性能参数
3. **服务注册**将服务注册到gRPC框架
4. **启动监听**:开始监听指定端口的连接
### 请求处理流程
```mermaid
flowchart TD
START([接收请求]) --> VALIDATE["验证请求格式"]
VALIDATE --> TRACE["设置追踪信息"]
TRACE --> CHECK_TYPE{"检查消息类型"}
CHECK_TYPE --> |连接请求| HANDLE_CONNECT["处理连接请求"]
CHECK_TYPE --> |下行请求| HANDLE_DOWNLINK["处理下行请求"]
HANDLE_CONNECT --> LOCK["获取锁"]
LOCK --> RESPOND["发送连接响应"]
RESPOND --> UNLOCK["释放锁"]
HANDLE_DOWNLINK --> CREATE_SESSION["创建协议会话"]
CREATE_SESSION --> PROCESS_CMD["处理命令"]
PROCESS_CMD --> LOG_RESULT["记录处理结果"]
UNLOCK --> END([处理完成])
LOG_RESULT --> END
```
**图表来源**
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L123-L184)
### 服务配置参数
| 参数 | 默认值 | 描述 |
|---------------------------------|----------|---------------|
| grpcPort | 9090 | gRPC服务端口 |
| grpcBoss | 4 | Boss线程数 |
| grpcWorker | 64 | Worker线程数 |
| grpcNettySoRcvbuf | 65535 | 接收缓冲区大小 |
| grpcNettySoSndbuf | 65535 | 发送缓冲区大小 |
| grpcNettyNoDelay | true | TCP_NODELAY选项 |
| maxInboundMessageSize | 33554432 | 最大消息大小32MB |
| maxConcurrentCallsPerConnection | 4 | 每连接最大并发调用数 |
| clientMaxKeepAliveTimeSec | 30 | 客户端最大保活时间 |
**节来源**
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L47-L60)
## 错误处理机制
### gRPC状态码
gRPC定义了标准的状态码体系系统遵循这些规范
| 状态码 | 名称 | 描述 |
|-----|---------------------|---------|
| 0 | OK | 操作成功完成 |
| 1 | CANCELLED | 操作被取消 |
| 2 | UNKNOWN | 未知错误 |
| 3 | INVALID_ARGUMENT | 无效参数 |
| 4 | DEADLINE_EXCEEDED | 超时 |
| 5 | NOT_FOUND | 资源未找到 |
| 6 | ALREADY_EXISTS | 资源已存在 |
| 7 | PERMISSION_DENIED | 权限不足 |
| 8 | RESOURCE_EXHAUSTED | 资源耗尽 |
| 9 | FAILED_PRECONDITION | 前置条件不满足 |
| 10 | ABORTED | 操作中止 |
| 11 | OUT_OF_RANGE | 范围错误 |
| 12 | UNIMPLEMENTED | 未实现 |
| 13 | INTERNAL | 内部错误 |
| 14 | UNAVAILABLE | 服务不可用 |
| 15 | DATA_LOSS | 数据丢失 |
| 16 | UNAUTHENTICATED | 未认证 |
### 异常处理策略
```mermaid
flowchart TD
ERROR[捕获异常] --> CLASSIFY{"分类异常"}
CLASSIFY --> |网络异常| RETRY["重试机制"]
CLASSIFY --> |认证异常| AUTH["重新认证"]
CLASSIFY --> |业务异常| BUSINESS["业务处理"]
CLASSIFY --> |系统异常| FATAL["致命错误"]
RETRY --> BACKOFF["指数退避"]
BACKOFF --> MAX_RETRY{"达到最大重试次数?"}
MAX_RETRY --> |否| RETRY
MAX_RETRY --> |是| FALLBACK["降级处理"]
AUTH --> RECONNECT["重新连接"]
BUSINESS --> LOG_ERROR["记录错误"]
FATAL --> SHUTDOWN["优雅关闭"]
FALLBACK --> NOTIFY["通知监控"]
LOG_ERROR --> NOTIFY
RECONNECT --> NOTIFY
SHUTDOWN --> NOTIFY
```
### 客户端错误处理
DownlinkGrpcClient实现了多层次的错误处理机制
1. **连接级错误**:连接断开时的处理
2. **消息级错误**:单条消息发送失败的处理
3. **会话级错误**:会话状态异常的处理
4. **系统级错误**:系统资源不足的处理
### 服务端错误处理
DownlinkGrpcService的错误处理重点关注
1. **请求验证**:确保请求格式正确
2. **会话管理**:处理会话状态异常
3. **资源保护**:防止资源耗尽
4. **优雅降级**:在异常情况下保持服务可用
**节来源**
- [DownlinkGrpcClient.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/grpc/DownlinkGrpcClient.java#L250-L297)
- [DownlinkGrpcService.java](file://jcpp-protocol-api/src/main/java/sanbing/jcpp/protocol/adapter/DownlinkGrpcService.java#L160-L184)
## 性能优化配置
### 网络参数优化
系统提供了丰富的网络参数配置,以适应不同的网络环境和性能需求:
| 参数类别 | 配置项 | 推荐值 | 说明 |
|-------|-------------|----------|-----------|
| 线程池 | boss线程数 | CPU核心数×2 | 处理新连接 |
| 线程池 | worker线程数 | CPU核心数×4 | 处理I/O操作 |
| 缓冲区 | SO_RCVBUF | 65535 | 接收缓冲区 |
| 缓冲区 | SO_SNDBUF | 65535 | 发送缓冲区 |
| TCP选项 | TCP_NODELAY | true | 禁用Nagle算法 |
| 消息大小 | 最大消息大小 | 32MB | 根据实际需求调整 |
| 并发控制 | 最大并发调用 | 4 | 防止资源耗尽 |
### 连接管理优化
```mermaid
graph LR
subgraph "连接生命周期"
A[连接建立] --> B[心跳检测]
B --> C[消息传输]
C --> D[空闲检测]
D --> E{是否空闲?}
E --> |是| F[保持连接]
E --> |否| C
F --> G[连接关闭]
end
subgraph "优化策略"
H[连接池] --> I[复用连接]
J[心跳保活] --> K[及时发现断连]
L[批量处理] --> M[提高吞吐量]
N[异步处理] --> O[降低延迟]
end
```
### 消息处理优化
1. **批量处理**:将多个小消息合并为大批量消息
2. **异步处理**使用独立线程池处理gRPC消息
3. **内存管理**:合理控制消息队列大小
4. **压缩传输**:启用消息压缩减少网络开销
### 监控指标
系统监控的关键性能指标:
| 指标类型 | 指标名称 | 描述 |
|------|--------|--------------|
| 吞吐量 | 消息处理速率 | 每秒处理的消息数量 |
| 延迟 | 响应时间 | 从请求到响应的时间 |
| 错误率 | 失败请求比例 | 失败请求占总请求的比例 |
| 资源使用 | CPU使用率 | gRPC服务的CPU占用 |
| 资源使用 | 内存使用率 | gRPC服务的内存占用 |
| 连接状态 | 活跃连接数 | 当前活跃的gRPC连接数 |
**节来源**
- [protocol-service.yml](file://jcpp-protocol-bootstrap/src/main/resources/protocol-service.yml#L50-L59)
- [app-service.yml](file://jcpp-app-bootstrap/src/main/resources/app-service.yml#L271-L280)
## 适用场景对比
### gRPC vs REST API
| 对比维度 | gRPC | REST API |
|-------|------------------|------------------|
| 序列化格式 | Protocol Buffers | JSON/XML |
| 性能 | 更快,更小的包体积 | 较慢,较大的包体积 |
| 类型安全 | 编译时检查 | 运行时检查 |
| 流式通信 | 支持双向流式 | 通常为请求-响应模式 |
| 版本控制 | 向前向后兼容 | 需要URL版本控制 |
| 跨语言支持 | 自动生成代码 | 需要手动实现 |
| 生态系统 | 较新的生态系统 | 成熟稳定的生态系统 |
| 学习曲线 | 中等 | 较低 |
| 适用场景 | 实时通信,微服务间通信 | Web API传统HTTP应用 |
### 选择建议
#### 使用gRPC的场景
1. **高频通信**:需要频繁交换大量数据
2. **实时性要求高**:需要低延迟的实时通信
3. **微服务架构**:服务间需要高效通信
4. **移动应用**:需要节省带宽和电量
5. **IoT设备**:资源受限的设备通信
#### 使用REST API的场景
1. **浏览器访问**需要通过Web浏览器访问
2. **简单查询**简单的CRUD操作
3. **公开API**面向公众的API服务
4. **现有系统集成**与已有REST系统集成
5. **调试友好**:需要易于调试和测试
### 性能对比
```mermaid
graph TB
subgraph "性能指标对比"
A[序列化速度] --> B[gRPC: 200MB/s<br/>REST: 100MB/s]
C[包体积] --> D[gRPC: 30%<br/>REST: 100%]
E[延迟] --> F[gRPC: 1ms<br/>REST: 10ms]
G[吞吐量] --> H[gRPC: 10K+ TPS<br/>REST: 1K+ TPS]
end
subgraph "资源消耗"
I[CPU使用] --> J[gRPC: 60%<br/>REST: 80%]
K[内存使用] --> L[gRPC: 70%<br/>REST: 90%]
M[网络带宽] --> N[gRPC: 50%<br/>REST: 100%]
end
```
## 最佳实践指南
### 客户端开发最佳实践
1. **连接池管理**
```java
// 推荐:使用连接池而非每次都创建新连接
ManagedChannel channel = channelMap.computeIfAbsent(hostAndPort,
key -> createNewChannel(key));
```
2. **错误处理**
```java
// 推荐:实现重试机制
@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))
public void sendRequestWithRetry(RequestMsg request) {
// 实现重试逻辑
}
```
3. **资源清理**
```java
// 推荐:确保资源正确释放
@PreDestroy
public void cleanup() {
channelMap.values().forEach(ManagedChannel::shutdownNow);
inputStreamMap.values().forEach(StreamObserver::onCompleted);
}
```
### 服务端开发最佳实践
1. **并发控制**
```java
// 推荐:限制并发连接数
@Value("${grpc.maxConcurrentCallsPerConnection:4}")
private int maxConcurrentCallsPerConnection;
```
2. **资源隔离**
```java
// 推荐:使用独立线程池处理业务逻辑
ExecutorService businessExecutor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors());
```
3. **监控告警**
```java
// 推荐:添加监控指标
@Monitor(name = "grpc.request.count")
public void monitorRequests() {
// 实现监控逻辑
}
```
### 性能调优建议
1. **网络层面**
- 调整TCP缓冲区大小
- 启用TCP_NODELAY
- 优化网络拓扑结构
2. **应用层面**
- 合理设置线程池大小
- 使用连接池复用连接
- 实现消息批处理
3. **系统层面**
- 监控系统资源使用
- 设置合理的超时时间
- 实现优雅的降级策略
### 安全考虑
1. **传输安全**
- 在生产环境中使用TLS加密
- 实施证书验证
- 定期更新加密算法
2. **访问控制**
- 实施身份认证
- 设置权限控制
- 记录访问日志
3. **数据保护**
- 敏感数据加密
- 实施数据脱敏
- 定期备份恢复
### 调试和诊断
1. **日志记录**
```java
// 推荐:添加详细的日志记录
log.info("Sending gRPC request: {}", request);
log.debug("Received gRPC response: {}", response);
```
2. **追踪监控**
```java
// 推荐:实施分布式追踪
TracerContextUtil.newTracer(traceId, origin, timestamp);
```
3. **性能分析**
```java
// 推荐:监控关键性能指标
Metrics.counter("grpc.requests.total").increment();
Metrics.timer("grpc.response.time").record(duration);
```
通过遵循这些最佳实践可以充分发挥gRPC的优势构建高性能、可靠的充电桩通信系统。