4.7 KiB
4.7 KiB
上电触发响应处理优化说明
优化目标
在上电触发场景下,在协议解码之前拦截设备回复,直接匹配到等待的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)
优势
-
减少通信负担
- 不需要走完整的协议解码流程
- 不需要发送到MQ异步处理
- 直接同步匹配,响应更快
-
提高精准度
- 直接匹配等待的request,不依赖协议特征识别
- 避免协议解码误判导致的问题
-
降低延迟
- 200ms内设备回复,立即匹配成功
- 无需等待协议解码和MQ处理
代码修改
1. PowerOnTriggerResponseHandler.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
channel.pipeline()
.addLast(FastBeeConstant.SERVER.ADAPTER, adapter)
.addLast("powerOnTriggerHandler", powerOnTriggerHandler) // 新增
.addLast(FastBeeConstant.SERVER.DECODER, decoder)
// ...
使用说明
当前实现
- 匹配成功:
requestR()立即返回,PowerOnTriggerTaskExecutor收到响应 - 继续传递:消息继续传递给协议解码器(可选,如果不想走协议解码可以注释掉)
如果不想走协议解码
如果完全不想走协议解码,可以修改PowerOnTriggerResponseHandler:
if (matched) {
log.debug("=>上电触发-设备回复已匹配,设备编号:{}", session.getClientId());
// 匹配成功,直接消费掉,不走协议解码
byteBuf.release(); // 释放ByteBuf
return; // 不继续传递
}
注意事项
-
ByteBuf引用计数
- 使用
byteBuf.retain()增加引用计数 - 如果匹配失败,需要
release()释放 - 如果匹配成功,后续处理器会负责释放
- 使用
-
兼容性
- 如果匹配失败,继续走正常流程(协议解码等)
- 不影响其他功能
-
性能
- 只在上电触发场景下生效
- 其他场景继续走正常流程
测试建议
-
验证匹配成功
- 下发上电触发指令
- 设备回复后,检查
requestR()是否立即返回 - 检查
PowerOnTriggerTaskExecutor是否正确更新任务状态
-
验证性能
- 对比优化前后的响应时间
- 检查是否减少了MQ消息量
-
验证兼容性
- 确保其他功能不受影响
- 确保协议解码仍然正常工作