mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-05-16 07:48:34 +08:00
update 桩端连接相关内容,解决频繁登录
This commit is contained in:
@@ -19,6 +19,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* 充电桩心跳包
|
||||
* 优化:将所有异步操作完全异步化,先返回心跳应答再执行其他逻辑
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -50,12 +51,6 @@ public class HeartbeatRequestHandler extends AbstractYkcHandler {
|
||||
byte[] pileSnByte = BytesUtil.copyBytes(msgBody, startIndex, length);
|
||||
String pileSn = BytesUtil.binary(pileSnByte, 16);
|
||||
|
||||
// 保存时间
|
||||
saveLastTimeAndCheckChannel(pileSn, channel);
|
||||
|
||||
// 校验channel
|
||||
// PileChannelEntity.checkChannel(pileSn, channel);
|
||||
|
||||
// 枪号
|
||||
startIndex += length;
|
||||
length = 1;
|
||||
@@ -69,30 +64,27 @@ public class HeartbeatRequestHandler extends AbstractYkcHandler {
|
||||
String connectorStatus = BytesUtil.binary(connectorStatusByte, 16);
|
||||
// log.info("桩号:{}, 枪号:{}, 枪状态:{}", pileSn, pileConnectorNum, connectorStatus);
|
||||
|
||||
// updateStatus(pileSn, pileConnectorNum, connectorStatus);
|
||||
// 优化:先构建并返回心跳应答,不阻塞心跳回复
|
||||
byte[] flag = Constants.zeroByteArray;
|
||||
byte[] messageBody = Bytes.concat(pileSnByte, pileConnectorNumByte, flag);
|
||||
byte[] response = getResult(ykcDataProtocol, messageBody);
|
||||
|
||||
// 公共方法修改状态
|
||||
// try {
|
||||
// pileBasicInfoService.updateStatus(BytesUtil.bcd2Str(ykcDataProtocol.getFrameType()), pileSn, pileConnectorNum, connectorStatus, null);
|
||||
// } catch (Exception e) {
|
||||
// log.error("公共方法修改状态error", e);
|
||||
// }
|
||||
|
||||
// 异步修改状态
|
||||
// 优化:所有其他操作(Redis、数据库)完全异步化,不阻塞心跳回复
|
||||
// 将 saveLastTimeAndCheckChannel 和 updateStatus 都改为异步执行
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
pileBasicInfoService.updateStatus(BytesUtil.bcd2Str(ykcDataProtocol.getFrameType()), pileSn, pileConnectorNum, connectorStatus, null);
|
||||
// 异步保存连接时间并检查通道(Redis 操作)
|
||||
saveLastTimeAndCheckChannel(pileSn, channel);
|
||||
|
||||
// 异步更新状态(数据库操作)
|
||||
String frameType = BytesUtil.bcd2Str(ykcDataProtocol.getFrameType());
|
||||
pileBasicInfoService.updateStatus(frameType, pileSn, pileConnectorNum, connectorStatus, null);
|
||||
} catch (Exception e) {
|
||||
log.error("公共方法修改状态error", e);
|
||||
log.error("心跳异步处理error, pileSn:{}", pileSn, e);
|
||||
}
|
||||
}, executor);
|
||||
|
||||
// 心跳应答(置0)
|
||||
byte[] flag = Constants.zeroByteArray;
|
||||
|
||||
// 消息体
|
||||
byte[] messageBody = Bytes.concat(pileSnByte, pileConnectorNumByte, flag);
|
||||
return getResult(ykcDataProtocol, messageBody);
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class NettyServerChannelInitializer extends ChannelInitializer<SocketChan
|
||||
pipeline.addLast(new IdleStateHandler(30, 0, 0, TimeUnit.SECONDS));
|
||||
// pipeline.addLast("handler", nettyServerHandler);
|
||||
pipeline.addLast(businessGroup, nettyServerHandler); // 消息先进入业务线程池
|
||||
pipeline.addLast(echoServerHandler);
|
||||
pipeline.addLast(businessGroup, echoServerHandler); // 回复Handler也绑定到业务线程池,避免阻塞IO线程
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -132,19 +132,23 @@ public class NettyServerHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
|
||||
long startTime = System.currentTimeMillis();
|
||||
String pileSn = "";
|
||||
String frameTypeStr = "";
|
||||
|
||||
try {
|
||||
YKCDataProtocol ykcDataProtocol = (YKCDataProtocol) message;
|
||||
// 获取帧类型
|
||||
byte[] frameTypeBytes = ykcDataProtocol.getFrameType();
|
||||
String frameType = YKCUtils.frameType2Str(frameTypeBytes);
|
||||
frameTypeStr = YKCUtils.frameType2Str(frameTypeBytes);
|
||||
// 获取序列号域
|
||||
int serialNumber = BytesUtil.bytesToIntLittle(ykcDataProtocol.getSerialNumber());
|
||||
// 获取channel
|
||||
Channel channel = ctx.channel();
|
||||
// 心跳包0x03日志太多,造成日志文件过大,改为不打印
|
||||
if (!CollectionUtils.containsAny(notPrintFrameTypeList, frameType)) {
|
||||
if (!CollectionUtils.containsAny(notPrintFrameTypeList, frameTypeStr)) {
|
||||
log.info("【<<<<<平台收到消息<<<<<】channel:{}, 帧类型:{}, 帧名称:{}, 序列号域:{}, 报文:{}",
|
||||
channel.id(), frameType, YKCFrameTypeCode.getFrameTypeStr(frameType), serialNumber,
|
||||
channel.id(), frameTypeStr, YKCFrameTypeCode.getFrameTypeStr(frameTypeStr), serialNumber,
|
||||
BytesUtil.binary(ykcDataProtocol.getBytes(), 16));
|
||||
}
|
||||
// 处理数据
|
||||
@@ -154,18 +158,26 @@ public class NettyServerHandler extends ChannelInboundHandlerAdapter {
|
||||
ByteBuf buffer = ctx.alloc().buffer().writeBytes(response);
|
||||
// this.channelWrite(channel.id(), buffer);
|
||||
super.channelRead(ctx, buffer);
|
||||
if (!CollectionUtils.containsAny(notPrintFrameTypeList, frameType)) {
|
||||
if (!CollectionUtils.containsAny(notPrintFrameTypeList, frameTypeStr)) {
|
||||
// 应答帧类型
|
||||
byte[] responseFrameTypeBytes = YKCFrameTypeCode.PlatformAnswersRelation.getResponseFrameTypeBytes(frameTypeBytes);
|
||||
String responseFrameType = YKCUtils.frameType2Str(responseFrameTypeBytes);
|
||||
log.info("【>>>>>平台响应消息>>>>>】channel:{}, 响应帧类型:{}, 响应帧名称:{}, 原帧类型:{}, 原帧名称:{}, 序列号域:{}, response:{}",
|
||||
channel.id(), responseFrameType, YKCFrameTypeCode.getFrameTypeStr(responseFrameType),
|
||||
frameType, YKCFrameTypeCode.getFrameTypeStr(frameType), serialNumber,
|
||||
frameTypeStr, YKCFrameTypeCode.getFrameTypeStr(frameTypeStr), serialNumber,
|
||||
BytesUtil.binary(response, 16));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
ReferenceCountUtil.release(message);
|
||||
|
||||
// 优化:增加消息处理耗时监控,用于排查性能问题
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
// 心跳帧(0x03)处理超过50ms警告,其他帧超过200ms警告
|
||||
int warnThreshold = "0x03".equals(frameTypeStr) ? 50 : 200;
|
||||
if (elapsed > warnThreshold) {
|
||||
log.error("【性能警告】消息处理耗时过长: {}ms, 帧类型: {}, pileSn: {}", elapsed, frameTypeStr, pileSn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user