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);
    }
	// ....
}

四 模拟断线重连

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

服务端图片效果如下

客户端图片效果如下

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

图片效果如下

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

本套教程

posted @   知识追寻者  阅读(1927)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示