| 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<AgvPackage> { | 
|   | 
|     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); | 
|                 } | 
|             } | 
|         } | 
|     } | 
|   | 
| } |