1. 程式人生 > >netty服務端實現心跳超時的主動拆鏈

netty服務端實現心跳超時的主動拆鏈

use ctx out apt ket cond else pipeline ali

一、服務器啟動示例:

public class MySocketServer {
    protected static Logger logger = LoggerFactory.getLogger(MySocketServer.class);

    public void start(int port) {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b 
= new ServerBootstrap(); b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new SocketServerInitializer()); logger.debug("server side socket start successful on port {}", port); b.bind(port).sync().channel().closeFuture().sync(); }
catch (InterruptedException e) { e.printStackTrace(); logger.error("{}", e.getMessage()); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }

二、各種業務Handler:

public class SocketServerInitializer extends
ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline() .addLast(new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS)) // 構造一個超時event消息 .addLast(new IdleStateTrigger()) // 處理超時event消息 .addLast(new StringDecoder()) .addLast(new StringEncoder()) .addLast(new ServerHandler()); } }

三、讀空閑(超過10s)的事件處理

public class IdleStateTrigger extends ChannelInboundHandlerAdapter {
    protected static Logger logger = LoggerFactory.getLogger(IdleStateTrigger.class);

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleState state = ((IdleStateEvent) evt).state();
            logger.debug("state is {}", state.name());
            if (state == IdleState.READER_IDLE) {
                ctx.close(); // 如果是超過10s沒有讀到數據,關閉客戶端連接
                throw new Exception("idle exception");
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

}

附錄、超時功能的快捷實現
使用自帶的ReadTimeoutHandler

public class SocketServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
         ch.pipeline()
        .addLast(new StringDecoder())
        .addLast(new StringEncoder())
        .addLast(new ReadTimeoutHandler(10, TimeUnit.SECONDS))
        .addLast(new ServerHandler());
    }
}

netty服務端實現心跳超時的主動拆鏈