Netty的相关组件之间的关系

组件类型

通常分为Client和Server两个,其中如果作为Client通常只需要一个EventLoopGroup并且是用Bootrap绑定该EventLoopGroup用作客户端去监听服务器端的ip和端口。而Server通常是用ServerBootrap绑定两个EventLoopGroup,一个用作连接一个用作处理事务

  • EventLoopGroup:管理EventLoop
  • EventLoop:处理多个Channel事件
  • Channel:代表一个网络连接(有多个ip连接就有多个channel)
  • Pipeline:处理 Channel 的数据流
  • Handler:用于处理网络事件,如数据读取、写入、连接建立,例如编解码、发送接收数据、心跳检测、加密解密等等

流程与启动执行顺序

通常是先设定一个EventLoopGroup,再设定Bootrap绑定该EventLoopGroup,其中可以通过intiChannel方法设定一些Handler实现一些逻辑。

this.bootstrap
          .group(this.group)
          .channel(NioSocketChannel.class)
          .handler(
              new ChannelInitializer<NioSocketChannel>() {
                @Override
                protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                  nioSocketChannel
                      .pipeline()
                      .addLast(
                          new ByteArrayEncoder(), // 发送字节数据 使用原始的ByteBuf进行传输
                          new PrinterStatusHandler());
                }
              });

当有ip与Bootrap进行连接的时候(调用Bootstrap.connect()方法),EventLoopGroup会选取一个EventLoop 就来绑定这一个线程,负责处理一个或多个 Channel 的事件,并且分配一个Channel绑定在该EventLoop上去处理这个ip进行通信(注意:每次调用 Bootstrap.connect() 都会创建一个新的 Channel,如果是同一个ip再去调用connect()方法是会新建Channel去连接这个ip导致Channel重复被创建取消,这没有被复用到,通常来说只要不主动断开连接或者调用close()方法Channel都会与其一直进行连接),然后每个Channel里包含pipeline,里面都会经历过所有Handler来进行对应逻辑处理。

同时给一个个人的小建议:通常来说都会独立编写connect()和send()两个操作,要记得保证connect()先正常连接再调用send()如下:

 public void connect(){
        ChannelFuture future = this.bootstrap.connect(ip, Integer.parseInt(port));
        // 避免同步连接阻塞
        future.addListener((ChannelFutureListener) f -> {
            if (f.isSuccess()) {
                System.out.println("成功连接到ip为:"+ip+port+"");
                log.info("成功连接到ip为:{}:{}" ,ip ,port);
                channel = f.channel();
            } else {
                log.error("连接到ip为:{}:{}失败" ,ip ,port);
            }
        });

        // 监听当前channel的关闭事件
        future.channel().closeFuture().addListener((ChannelFutureListener) f -> {
            log.info("打印机已关闭");
            statusCallback.put(statusKey , PrinterStatus.FAULT);
            System.out.println("已关闭");
            // 延迟 5 秒后重新连接
            if(retryConnectCount.get() > 0){
                log.info("正在重新尝试连接");
                f.channel().eventLoop().schedule(this::connect, 3, TimeUnit.SECONDS);
                retryConnectCount.decrementAndGet();
            }else {
                retryConnectCount.set(3);
                log.error("重新尝试连接");
            }
        });
    }

public void send(){
        //等待异步的channel被设置好
        sleep(1000);
        if(channel != null && channel.isActive()){
            channel.writeAndFlush(new byte[]{0x10, 0x04, 0x01});
        }else{
            System.out.println("当前Channel已失活");
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kkoneone11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值