fastbee/上电触发响应处理优化说明.md
2025-12-30 08:02:52 +08:00

164 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 上电触发响应处理优化说明
## 优化目标
在上电触发场景下,**在协议解码之前拦截设备回复**,直接匹配到等待的`requestR()`调用,避免走完整的协议解码和MQ流程,减少通信负担,提高响应速度。
## 实现方案
### 1. 新增Handler:PowerOnTriggerResponseHandler
**位置:** `fastbee-server/iot-server-core/src/main/java/com/fastbee/server/handler/PowerOnTriggerResponseHandler.java`
**功能:**
- 在协议解码之前拦截设备回复的原始ByteBuf数据
- 创建简单的Message对象(不解析内容)
- 调用`Session.response()`尝试匹配到等待的`requestR()`调用
- 如果匹配成功,`requestR()`会立即返回,无需等待协议解码
### 2. Handler链顺序
```
TCPMessageAdapter (接收原始ByteBuf)
↓
PowerOnTriggerResponseHandler (拦截并匹配响应) ← 新增
↓
MessageDecoderWrapper (协议解码)
↓
DispatcherHandler (消息分发)
```
### 3. 工作原理
```
1. 平台下发指令
PowerOnTriggerTaskExecutor.execute()
→ MessageManager.requestR()
→ Session.request() 订阅等待响应
2. 设备回复原始字节数据
设备发送:ByteBuf (例如:7E 01 03 00 00 00 02 C4 0B 7E)
3. PowerOnTriggerResponseHandler拦截
- 接收原始ByteBuf
- 创建简单的Message对象(不解析内容)
- 调用Session.response()尝试匹配
4. 匹配成功
- Session.response()找到等待的request
- 立即唤醒等待的Mono
- requestR()返回成功(code=200, data=Message对象)
- PowerOnTriggerTaskExecutor收到响应,更新任务状态
5. 继续传递(可选)
- 如果继续传递,协议解码也会处理(但上电触发任务已完成)
- 如果不想走协议解码,可以注释掉ctx.fireChannelRead(msg)
```
## 优势
1. **减少通信负担**
- 不需要走完整的协议解码流程
- 不需要发送到MQ异步处理
- 直接同步匹配,响应更快
2. **提高精准度**
- 直接匹配等待的request,不依赖协议特征识别
- 避免协议解码误判导致的问题
3. **降低延迟**
- 200ms内设备回复,立即匹配成功
- 无需等待协议解码和MQ处理
## 代码修改
### 1. PowerOnTriggerResponseHandler.java
```java
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
Packet packet = (Packet) msg;
Session session = packet.session;
ByteBuf byteBuf = packet.byteBuf;
// 创建简单的Message对象,只用于匹配响应
Message responseMessage = new Message();
responseMessage.setClientId(session.getClientId());
responseMessage.setPayload(byteBuf.retain());
// 尝试匹配到等待的request
boolean matched = session.response(responseMessage);
if (matched) {
log.debug("=>上电触发-设备回复已匹配,设备编号:{}", session.getClientId());
// 匹配成功,继续传递(可选)
ctx.fireChannelRead(msg);
} else {
// 没有匹配到,继续正常流程
responseMessage.getPayload().release();
ctx.fireChannelRead(msg);
}
}
```
### 2. TCPServer.java
```java
channel.pipeline()
.addLast(FastBeeConstant.SERVER.ADAPTER, adapter)
.addLast("powerOnTriggerHandler", powerOnTriggerHandler) // 新增
.addLast(FastBeeConstant.SERVER.DECODER, decoder)
// ...
```
## 使用说明
### 当前实现
- **匹配成功**:`requestR()`立即返回,`PowerOnTriggerTaskExecutor`收到响应
- **继续传递**:消息继续传递给协议解码器(可选,如果不想走协议解码可以注释掉)
### 如果不想走协议解码
如果完全不想走协议解码,可以修改`PowerOnTriggerResponseHandler`:
```java
if (matched) {
log.debug("=>上电触发-设备回复已匹配,设备编号:{}", session.getClientId());
// 匹配成功,直接消费掉,不走协议解码
byteBuf.release(); // 释放ByteBuf
return; // 不继续传递
}
```
### 注意事项
1. **ByteBuf引用计数**
- 使用`byteBuf.retain()`增加引用计数
- 如果匹配失败,需要`release()`释放
- 如果匹配成功,后续处理器会负责释放
2. **兼容性**
- 如果匹配失败,继续走正常流程(协议解码等)
- 不影响其他功能
3. **性能**
- 只在上电触发场景下生效
- 其他场景继续走正常流程
## 测试建议
1. **验证匹配成功**
- 下发上电触发指令
- 设备回复后,检查`requestR()`是否立即返回
- 检查`PowerOnTriggerTaskExecutor`是否正确更新任务状态
2. **验证性能**
- 对比优化前后的响应时间
- 检查是否减少了MQ消息量
3. **验证兼容性**
- 确保其他功能不受影响
- 确保协议解码仍然正常工作