fix(netty): 优化异常处理和心跳超时逻辑

- 改进异常捕获日志格式,添加channel哈希值标识
- 修正异常处理逻辑,确保合法连接断开时调用离线服务
- 优化心跳超时处理,统一连接关闭逻辑
- 添加详细的注释说明异常处理和超时断连策略
This commit is contained in:
2026-04-10 10:34:45 +08:00
parent dc14a57686
commit cf72d1c704

View File

@@ -127,15 +127,15 @@ public class ServerHandler extends SimpleChannelInboundHandler<String> {
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
logger.error("ServerHandler exceptionCaught",cause);
Channel channel = ctx.channel();
ChannelParam param = ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get();
// Integer venueId = ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().getVenueId();
// String deviceName = ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().getDeviceName();
// DeviceType deviceType = ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().getDeviceType();
// messageService.Offline(deviceName,venueId,deviceType);
logger.error("{} - ServerHandler exceptionCaught",channel.hashCode(),cause);
if(channel.isActive()) {
ChannelParam param = channel.attr(NettyConstant.CHANNEL_PARAM).get();
// 无论是合法连接还是非法扫描发来的乱码,发生错误立马掐断连接,绝不能手软
if(channel.isActive() && param != null && param.getVenueId() != null) {
// 错误产生,关闭连接
messageService.Offline(param.getDeviceName(),param.getVenueId());
logger.info("{} - {} ServerHandler exceptionCaught{}",channel.hashCode(),param.getDeviceName(),param.getVenueId(),cause);
}
ctx.close();
}
}
@@ -149,18 +149,21 @@ public class ServerHandler extends SimpleChannelInboundHandler<String> {
if (evt instanceof IdleStateEvent){
IdleState state = ((IdleStateEvent) evt).state();
if (state == IdleState.READER_IDLE){
logger.info("IdleStateEvent READER_IDLE 超时");
ChannelParam param = ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get();
if (param != null && param.getVenueId() != null) {
// 原有逻辑
Integer venueId = ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().getVenueId();
String deviceName = ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().getDeviceName();
messageService.Offline(deviceName,venueId);
ctx.channel().close();
}
logger.info("IdleStateEvent READER_IDLE 超时,主动断开连接");
Channel channel = ctx.channel();
ChannelParam param = channel.attr(NettyConstant.CHANNEL_PARAM).get();
if(channel.isActive() && param != null && param.getVenueId() != null) {
logger.info("{} IdleStateEvent READER_IDLE 超时,{}主动断开连接",param.getDeviceName(),param.getVenueId());
}
// 无论是否是有效设备只要读超时120秒未收到任何数据就应该关闭连接。
// 关闭连接会触发 channelInactive在 channelInactive 中会根据 venueId 判断是否需要处理离线逻辑。
channel.close();
}
}
// 由于每次 Idle 都会打日志显得冗余,这里只在有必要时看
Set<String> connections = messageService.countConnection();
// 如果想要干净的日志,这个连接池统计其实可以去掉,或者缩小为 DEBUG
logger.info("count connected device ! the count is " + connections.size() + " and they are + [" + connections.toString() + "]" );
}