# 上电触发响应处理优化说明 ## 优化目标 在上电触发场景下,**在协议解码之前拦截设备回复**,直接匹配到等待的`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. **验证兼容性** - 确保其他功能不受影响 - 确保协议解码仍然正常工作