Netty客户端断线重连

前提:假设你的客户端和服务端已经写好了的情况下

1.短线重连是客户端的事情——————》客户端一般这样写

客户端:

    private Channel channel;
    private Bootstrap bootstrap;

    public void client() throws InterruptedException {
        String ip = "localhost";
        Integer port = 9898;
        bootstrap = new Bootstrap();
        System.out.println(this.getClass());
        NioEventLoopGroup loopGroup = new NioEventLoopGroup();
        NettyTest t = this;
        bootstrap.group(loopGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.SO_BACKLOG, 1000)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(2048))
                .handler(new ChannelInitializer() {


                    @Override
                    protected void initChannel(Channel channel) throws Exception {
                        // 自己的处理器
                        channel.pipeline().addLast(new TestClientHandler(t));
                    }






                });
        try {
              ChannelFuture channelFuture = bootstrap.connect(ip,port).sync();
              clientChannelFuture.channel().closeFuture().sync()

        } finally {
            /**优雅退出,释放NIO线程组*/
            loopGroup.shutdownGracefully();
        }

处理器:

public class TestClientHandler extends ChannelInboundHandlerAdapter {

//    NettyTest nettyTest;
//
//    public TestClientHandler(NettyTest nettyTest) {
//        this.nettyTest = nettyTest;
//    }
    NettyTest nettyTest;
    public TestClientHandler(netty.test.NettyTest client) {
//        super("client");
        this.nettyTest = client;
    }

    public TestClientHandler(){}

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("连接成功");
        String reqMsg = "我是客户端 110 " + Thread.currentThread().getName();
        byte[] reqMsgByte = reqMsg.getBytes("UTF-8");
        ByteBuf reqByteBuf = Unpooled.buffer(reqMsgByte.length);
        /**
         * writeBytes:将指定的源数组的数据传输到缓冲区
         * 调用 ChannelHandlerContext 的 writeAndFlush 方法将消息发送给服务器
         */
        reqByteBuf.writeBytes(reqMsgByte);
        ctx.writeAndFlush(reqByteBuf);
    }

    /**
     * 当服务端返回应答消息时,channelRead 方法被调用,从 Netty 的 ByteBuf 中读取并打印应答消息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println(Thread.currentThread().getName() + ",Server return Message:" + body);
//        ctx.close();
    }
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        System.out.println("服务端断开:" + ctx.channel().remoteAddress());
        //TODO 断开后的重连接
      

    }

    /**
     * 当发生异常时,打印异常 日志,释放客户端资源
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        /**释放资源*/
//        ctx.close();
    }

断线重连改写

客户端:

    private Channel channel;
    private Bootstrap bootstrap;
    ClientChannelFuture clientChannelFuture;
    public void client() throws InterruptedException {
        String ip = "localhost";
        Integer port = 9898;
        bootstrap = new Bootstrap();
        System.out.println(this.getClass());
        NioEventLoopGroup loopGroup = new NioEventLoopGroup();
        NettyTest t = this;
        bootstrap.group(loopGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.SO_BACKLOG, 1000)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(2048))
                .handler(new ChannelInitializer() {


                    @Override
                    protected void initChannel(Channel channel) throws Exception {
//                        channel.pipeline().addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));
//                        String delimiter = "\r\n";
//                        int length = 40960;
//                        ByteBuf byteBuf = Unpooled.copiedBuffer(delimiter, CharsetUtil.UTF_8);
//                        channel.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(length, byteBuf));
                        channel.pipeline().addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));

                        channel.pipeline().addLast(new TestClientHandler(t));
                    }






                });
         try {
            this.doConnect();
            clientChannelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            log.info("启动出错 e", e);
        } finally { //优雅关闭功能
            log.info("SecureDeviceServer run finnally shutdown.");
//            loopGroup.shutdownGracefully();
        }
  
    }

    

    protected void doConnect() {
        if (channel != null && channel.isActive()) {
            return;
        }

        clientChannelFuture = bootstrap.connect("127.0.0.1", 9898);

        clientChannelFuture.addListener(new ChannelFutureListener() {
            public void operationComplete(ChannelFuture futureListener) throws Exception {
                if (futureListener.isSuccess()) {
                    channel = futureListener.channel();
                    System.out.println("Connect to server successfully!");
                } else {
                    System.out.println("Failed to connect to server, try connect after 10s");

                    futureListener.channel().eventLoop().schedule(new Runnable() {
                        @Override
                        public void run() {
                            doConnect();
                        }
                    }, 10, TimeUnit.SECONDS);
                }
            }
        });


    }

处理器:


    NettyTest nettyTest;
//
//    public TestClientHandler(NettyTest nettyTest) {
//        this.nettyTest = nettyTest;
//    }
    NettyTest nettyTest;
    public TestClientHandler(netty.test.NettyTest client) {
//        super("client");
        this.nettyTest = client;
    }

    public TestClientHandler(){}

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("连接成功");
        String reqMsg = "我是客户端 110 " + Thread.currentThread().getName();
        byte[] reqMsgByte = reqMsg.getBytes("UTF-8");
        ByteBuf reqByteBuf = Unpooled.buffer(reqMsgByte.length);
        /**
         * writeBytes:将指定的源数组的数据传输到缓冲区
         * 调用 ChannelHandlerContext 的 writeAndFlush 方法将消息发送给服务器
         */
        reqByteBuf.writeBytes(reqMsgByte);
        ctx.writeAndFlush(reqByteBuf);
    }

    /**
     * 当服务端返回应答消息时,channelRead 方法被调用,从 Netty 的 ByteBuf 中读取并打印应答消息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println(Thread.currentThread().getName() + ",Server return Message:" + body);
//        ctx.close();
    }
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        System.out.println("服务端断开:" + ctx.channel().remoteAddress());
        //TODO 断开后的重连接
        // 加入短线重连
       nettyTest.doConnect();

    }

    /**
     * 当发生异常时,打印异常 日志,释放客户端资源
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        /**释放资源*/
//        ctx.close();
    }

猜你喜欢

转载自www.cnblogs.com/white-123/p/11814261.html