zoukankan      html  css  js  c++  java
  • netty断线重连

    一 什么是断线重连

    断线重连是指由于发生网络故障而导致服务中断的情况,客户端就需要从重新连接服务端;哪些情况下会导致服务断线呢?常见 的就是 网络情况下,断断续续,导致客户端无法和服务端交互,再比如,机房断电也会导致服务宕机;所以在netty中对服务进行断线重连是非常有必要的做的一个流程;

    二 netty断线重连步骤

    netty 什么情况下需要断线重连?

    netty 刚刚启动时需要断线重连,有可能服务刚刚启动,连接失败,此时就可以尝试断线重连,保证服务正常运行;其次,当服务在运行过程中出现网络故障的时候需要断线重连,这样能保证服务即使宕机恢复后也能马上恢复;所以 netty 的断线重连需要 2 步骤,缺一不可;

    三 客户端断线重连

    netty 的服务端一般情况下不需要断线重连,应为服务端服务宕机就只能重新启动服务;所以今天我们研究的是客户端的断线重连;

    3.1 服务启动时断线重连

    首先 我们需要写一个监听器 实现 ChannelFutureListener 接口的 operationComplete 方法, 在这边 我们 使用构造器注入的方式获取 nettyClient 实例, 当客户端连接操作完成后启动一个负载监听,在方法中我们使用 channelFuture.isSuccess() 的 结果进行判定 客户端的连接是否启动成功;如果没有启动成功则启动新的线程进行重连,确保客户端连接时能连接成功;

    @Slf4j
    public class ConnectionListener implements ChannelFutureListener {
        private NettyClient nettyClient;
        public ConnectionListener(NettyClient nettyClient) {
            this.nettyClient = nettyClient;
        }
        @Override
        public void operationComplete(ChannelFuture channelFuture) throws Exception {
            if (!channelFuture.isSuccess()) {
                log.warn("-------------客户端重新连接-----------------");
                final EventLoop loop = channelFuture.channel().eventLoop();
                loop.schedule(new Runnable() {
                    @SneakyThrows
                    @Override
                    public void run() {
                        nettyClient.connect(8080,"127.0.0.1");
                    }
                }, 1L, TimeUnit.SECONDS);
            }
        }
    
    }
    

    这边我们只是实现了一个监听器,我们还需要把监听器注入到客户端;

    public void connect(int port, String host) {
    
            // 创建线程组
            NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
            // netty启动辅助类
            Bootstrap bootstrap = new Bootstrap();
            //
            bootstrap.group(nioEventLoopGroup)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            // 处理IO事件
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            // 异常断线重连
                            pipeline.addLast(new NettyClientHandler(new NettyClient()));
                        }
                    });
            // 异步操作
            ChannelFuture connect = null;
            try {
                connect = bootstrap
                        .connect(host, port)
                        .addListener(new ConnectionListener(this))// netty 启动时如果连接失败,会断线重连
                        .sync();
                // 关闭客户端
                connect.channel()
                        .closeFuture()
                        .sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    

    3.2 服务运行中断重连

    我们 在 NettyClientHandler 实现一个 channelInactive 方法,当服务端断线时 我们会触发这个方法重启启动一个线程进行断线重连;

    @Slf4j
    public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    
        private NettyClient nettyClient;
    
    
        public NettyClientHandler(NettyClient nettyClient) {
            this.nettyClient = nettyClient;
        }
    	// ....
    
        /**
         * @Author lsc
         * <p> 运行时断线重连</p>
         * @Param [ctx]
         * @Return
         */
        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            final EventLoop eventLoop = ctx.channel().eventLoop();
            eventLoop.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println("22222222222222222");
                    nettyClient.connect(8080, "127.0.0.1");
                }
            }, 1L, TimeUnit.SECONDS);
            super.channelInactive(ctx);
        }
    	// ....
    }
    

    四 模拟断线重连

    首先我们先启动 服务端和 客户端,知识追寻者 的代码有个应答 消息;

    服务端图片效果如下

    客户端图片效果如下

    将 服务端 停止 ,客户端会进行断线重连

    图片效果如下

    重新启动服务端,重连成功

    本套教程

  • 相关阅读:
    typescript-泛型-类型检查
    typescript-class-interface
    typescript-类class
    typescript-接口interface
    Oracle 密码过期
    VMware Redhat虚拟机扩容硬盘
    华硕 U系列电脑拆后盖注意事项
    VS + QT 出现 LNK2001 无法解析的外部符号 QMetaObject 的问题
    c++ _pFirstBlock == pHead
    c++ 套路多
  • 原文地址:https://www.cnblogs.com/zszxz/p/14513110.html
Copyright © 2011-2022 走看看