Netty心跳检测

实验

  • server
        serverBootstrap.group(bossGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 1024)
                //.childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new ChannelInitializer() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));
                        ch.pipeline().addLast(new StringEncoder());
                        ch.pipeline().addLast(new StringDecoder());
                        ch.pipeline().addLast(new ServerHandle());
                    }
                });

ch.pipeline().addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));服务端设置读超时

  • ServerHandle
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println(msg.toString());
        if (msg.equals("Heartbeat")) {
            System.out.println("recv Heartbeat!");
            ctx.write("has read message from server");
            ctx.flush();
        }
        super.channelRead(ctx, msg);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof IdleStateEvent){
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            if(idleStateEvent.state() == IdleState.READER_IDLE){
                loss_connect_time++;
                System.out.println(loss_connect_time);
                if(loss_connect_time>2){
                    System.out.println("close");
                    ctx.channel().close();
                }
            }
        }
        super.userEventTriggered(ctx, evt);
    }
  • client
        b.group(workGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(new ChannelInitializer() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast("ping",new IdleStateHandler(0,4,0, TimeUnit.SECONDS));
                        ch.pipeline().addLast(new StringDecoder());
                        ch.pipeline().addLast(new ClientHandler());
                    }
                });

client用ch.pipeline().addLast("ping",new IdleStateHandler(0,4,0, TimeUnit.SECONDS));添加写超时

  • ClientHandler
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        System.out.println("EventTriggered TIME : "+ new Date(System.currentTimeMillis()));
        if(evt instanceof IdleStateEvent){
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            if(idleStateEvent.state() == IdleState.WRITER_IDLE){
                if(currentTime < 3){
                    System.out.println("currentTime : "+ currentTime);
                    currentTime++;
                    ctx.writeAndFlush(HEARTBEAT_SEQUENCE.duplicate());
                }
            }
        }
        super.userEventTriggered(ctx, evt);
    }

HEARTBEAT_SEQUENCE.duplicate() 复制当前对象,复制后的对象与前对象共享缓冲区,且维护自己的独立索引

结果

  • server
connect!
QUERY TIME ORDER
Heartbeat
recv Heartbeat!
Heartbeat
recv Heartbeat!
Heartbeat
recv Heartbeat!
1
2
3
close
disconnected!
  • client
Send firstSendMsg!
Client read!
Now is :hello

EventTriggered TIME : Fri Dec 22 22:54:36 CST 2017
currentTime : 0
Client read!
Now is :has read message from server
EventTriggered TIME : Fri Dec 22 22:54:40 CST 2017
currentTime : 1
Client read!
Now is :has read message from server
EventTriggered TIME : Fri Dec 22 22:54:44 CST 2017
currentTime : 2
Client read!
Now is :has read message from server
EventTriggered TIME : Fri Dec 22 22:54:48 CST 2017
EventTriggered TIME : Fri Dec 22 22:54:52 CST 2017
EventTriggered TIME : Fri Dec 22 22:54:56 CST 2017
get : has read message from server
Relase group!

其他

  • 设置attr
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.channel().attr(AttributeKey.valueOf("attrTest")).set(msg);
//...
        super.channelRead(ctx, msg);
    }
public class NettyClient {
    public static void main(String[] args) {
       //...
        try {
            ChannelFuture connectFuture = b.connect(new InetSocketAddress("127.0.0.1", 8001)).sync();
            connectFuture.channel().closeFuture().sync();
            Object res = connectFuture.channel().attr(AttributeKey.valueOf("attrTest")).get();
            System.out.println("get : " + res.toString());
        } catch (InterruptedException e) {
          //...
        } finally {
 //...
        }
    }
}
  • ctx.write 和ctx.channel.write()

Any difference between ctx.write() and ctx.channel().write() in netty?

Channel.write() 和 ChannelHandlerContext.write() 的区别

你可能感兴趣的:(Netty心跳检测)