netty重连

  1. 简单的netty重连

    1. 首先是 有一个 netty 客户端;
`package com.example.nettySimple;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;

/**
 * @author Xia_Ye_bing
 * @PRODUCT_NAME IntelliJ IDEA
 * @creatime 2021 10 27 13:20
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client" + ctx); 
    }

    /**
     * 当通道有读取事件时 会触发,
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        final ByteBuf buf = (ByteBuf) msg;
        System.out.println("服务器回复的信息是 " + buf.toString(CharsetUtil.UTF_8));
        System.out.println("服务器地址为:" + ctx.channel().remoteAddress());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelUnregistered();
        System.out.println(" netty 链接失败,3秒后进行重连");
        Thread.sleep(3000);
        NettyClient.start();
    }

    @Override
    public void channelInactive(final ChannelHandlerContext ctx) {
        System.out.println("连接断开:" + ctx.channel().remoteAddress());
    }

}
  1. `创建一个处理器
  package com.example.nettySimple;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;

/**
 * @author Xia_Ye_bing
 * @PRODUCT_NAME IntelliJ IDEA
 * @creatime 2021 10 27 13:20
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client" + ctx);
    }

    /**
     * 当通道有读取事件时 会触发,
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        final ByteBuf buf = (ByteBuf) msg;
        System.out.println("服务器回复的信息是 " + buf.toString(CharsetUtil.UTF_8));
        System.out.println("服务器地址为:" + ctx.channel().remoteAddress());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelUnregistered();
        System.out.println(" netty 链接失败,3秒后进行重连");
        Thread.sleep(3000);
        NettyClient.start();
    }

    @Override
    public void channelInactive(final ChannelHandlerContext ctx) {
        System.out.println("连接断开:" + ctx.channel().remoteAddress());
    }

}
  1. 演示效果
  2. netty重连演示-url(需下载)
  3. 新建一个客户端
package com.example.nettySimple;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @author Xia_Ye_bing
 * @PRODUCT_NAME IntelliJ IDEA
 * @creatime 2021 10 27 7:19
 */
public class nrtty_siple {

    public static void main(String[] args) throws InterruptedException {
        /**
         * 创建两个 线程组 booGroup 和 workerGroup,
         * booGroup 只处理链接请求,
         * workerGroup 真正处理客户端业务处理
         * 两个都是 无线循环,两个线程的默认线程个数是 CPU核数*2,写了值话,按照写的个数创建线程数
         */
        final EventLoopGroup booGroup = new NioEventLoopGroup(1);

        final EventLoopGroup workerGroup = new NioEventLoopGroup();

        /**
         *    创建启动对象
         */
        final ServerBootstrap bootstrap = new ServerBootstrap();

        /**
         * 使用链式编程 来 设置 各个参数
         */

        bootstrap.group(booGroup, workerGroup)//设置里昂个线程组
                .channel(NioServerSocketChannel.class)//使用  NioServerSocketChannel 作为服务器的通道实现
                .option(ChannelOption.SO_BACKLOG, 128)//设置保持通道链接状态
                .childOption(ChannelOption.SO_KEEPALIVE, true)//对应的管道设置处理器
                .childHandler(new ChannelInitializer<SocketChannel>() {//创建一个通道初始化对象(匿名对象)
                    //给 pipeline 设置处理器
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(new nettySipleHandler());//将自定义的处理器加入
                    }
                });//给我们的workerGroup 的 EventLoopGroup 设置处理器
        System.out.println("服务器 is ready");
        //绑定一个端口 生成一个channelFuture 对象 同时启动服务器
        final ChannelFuture channelFuture = bootstrap.bind(6668).sync();
        //对关闭通道进行监听
        channelFuture.channel().closeFuture().sync();

    }
}

8 建立 客户端处理器

package com.example.nettySimple;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

/**
 * @author Xia_Ye_bing
 * @PRODUCT_NAME IntelliJ IDEA
 * @creatime 2021 10 27 7:40
 */

/**
 * 我,们自定义一个handler ,需要 继承 netty规定好的 某个 HandlerAdapter (规范)
 * 这时的handler 才是 一个 handler
 */
public class nettySipleHandler extends ChannelInboundHandlerAdapter {
    //读取数据事件 ()可以读取客户端发送的消息

    /**
     * @param ctx : ChannelHandlerContext ctx 上下文对象,含有 通道 、管道
     *            Object ms 客户端发发送的数据
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("server ctx" + msg);
        System.out.println("服务器读取线程   "+Thread.currentThread().getName());
        /**
         * 将msg转为bytebuf ,
         * bytebuf  是 netty 提供,不是 nio中的ByteBuffer
         */
        final ByteBuf buf = (ByteBuf) msg;
        System.out.println("客户端发送的消息是 " + buf.toString(CharsetUtil.UTF_8));
        System.out.println("客户端地址是:" + ctx.channel().remoteAddress());
    }

    //数据读取完毕
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

        /**
         * writeAndFlush 写并且发送
         * 将数据写入缓存并刷新
         * 需要对发送的数据进行编码
         */
        ctx.writeAndFlush(Unpooled.copiedBuffer(("hellow 客户端"), CharsetUtil.UTF_8));
    }

    //关闭通道、
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.channel().close();
    }
}

10 netty 重连 效果演示(演示时候,先开启 客户端,客户端 会 一直 重连,当 启动 服务端后,服务端 停止重连,当 断开 服务器时 ,服务端再次重连);

11、链接-断开-重连-效果演示(需下载)

13、文件源码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于Netty WebSocket的重连,你可以采取以下步骤: 1. 创建一个WebSocket重连管理类,用于管理WebSocket的连接状态和重连逻辑。 2. 在WebSocket连接断开时,触发重连逻辑。你可以在`channelInactive`方法中检测连接断开事件。 3. 在重连逻辑中,使用`Bootstrap`重新建立WebSocket连接。你可以在重连方法中创建一个新的`WebSocketClientHandler`并添加到`Bootstrap`中。 4. 设置重连的时间间隔,避免频繁重连。可以使用定时器来触发重连逻辑,并设置一个合理的重连间隔时间。 5. 如果重连成功,更新连接状态并进行后续操作。如果重连失败,可以继续触发下一次重连。 下面是一个简单的示例代码,演示了如何实现Netty WebSocket的重连: ```java public class WebSocketReconnectManager { private final EventLoopGroup eventLoopGroup; private final String host; private final int port; private final URI uri; private Bootstrap bootstrap; private WebSocketClientHandler clientHandler; private ScheduledFuture<?> reconnectFuture; private boolean connected; public WebSocketReconnectManager(EventLoopGroup eventLoopGroup, String host, int port, String path) throws URISyntaxException { this.eventLoopGroup = eventLoopGroup; this.host = host; this.port = port; this.uri = new URI("ws://" + host + ":" + port + path); init(); } private void init() { bootstrap = new Bootstrap(); clientHandler = new WebSocketClientHandler(bootstrap, uri); bootstrap.group(eventLoopGroup) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new HttpClientCodec()); pipeline.addLast(new HttpObjectAggregator(8192)); pipeline.addLast(clientHandler); } }); connect(); } private void connect() { bootstrap.connect(host, port).addListener((ChannelFutureListener) future -> { if (future.isSuccess()) { connected = true; } else { connected = false; scheduleReconnect(); } }); } private void scheduleReconnect() { if (!connected && reconnectFuture == null) { reconnectFuture = eventLoopGroup.schedule(this::connect, 5, TimeUnit.SECONDS); } } public void onConnected() { connected = true; if (reconnectFuture != null) { reconnectFuture.cancel(false); reconnectFuture = null; } } public void onDisconnected() { connected = false; scheduleReconnect(); } } ``` 在你的WebSocket客户端代码中,需要在连接断开时调用`onDisconnected`方法,当重连成功后调用`onConnected`方法。这样就能实现简单的WebSocket重连逻辑。你可以根据自己的需求进行调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值