package com.zy.acs.gateway.handler; import com.zy.acs.framework.common.Cools; import com.zy.acs.gateway.AbstractInboundHandler; import com.zy.acs.gateway.cache.ChannelCache; import com.zy.acs.gateway.domain.AgvPackage; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; import io.netty.util.ReferenceCountUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 通道维护handler * Created by vincent on 2019-04-11 */ @Component("protectorHandler") @ChannelHandler.Sharable public class ProtectorHandler extends AbstractInboundHandler { private static final Logger log = LoggerFactory.getLogger(ProtectorHandler.class); @Override protected boolean channelRead0(ChannelHandlerContext ctx, AgvPackage pac) throws Exception { // jvm堆外内存需要手动释放 ReferenceCountUtil.release(pac.getSourceBuff()); return true; } /** * 断开连接 */ @Override public void channelInactive(ChannelHandlerContext ctx) { String uniqueno = ChannelCache.removeChannel(ctx.channel()); ctx.close(); if (!Cools.isEmpty(uniqueno)){ log.info("Agv [{}] 失去连接", uniqueno); } } /** * 管道异常 */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { log.error("ProtectorHandler exceptionCaught", cause); if (cause instanceof IndexOutOfBoundsException) { log.error("Received malformed data, waiting for more input......"); } else { ChannelCache.removeChannel(ctx.channel()); ctx.close(); } } /** * 空闲剔除 */ @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (evt instanceof IdleStateEvent) { IdleStateEvent e = (IdleStateEvent) evt; if (IdleState.READER_IDLE == e.state()) { String uniqueno = ChannelCache.removeChannel(ctx.channel()); ctx.close(); if (!Cools.isEmpty(uniqueno)){ log.info("Agv [{}] 空闲剔除", uniqueno); } } } } }