Netty入门-组件Channel

3.2、Channel
  • close() 关闭channel
  • closeFuture() 用来处理channel的关闭
    • sync() 同步等待channel关闭
    • addListener() 异步等待channel关闭
  • pipeline() 添加处理器
  • write() 将数据写入缓冲区,但不会立即输出
  • wrireAndFlush() 写入并刷出

channelfuture详解

public class HelloClient {
    public static void main(String[] args) throws InterruptedException {
        //1. 启动类
        ChannelFuture channelFuture = new Bootstrap()
                //2. 添加EventLoop
                .group(new NioEventLoopGroup())
                //3. 选择客户端channel实现
                .channel(NioSocketChannel.class)
                //4. 添加处理器
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    //在连接建立后被调用
                    protected void initChannel(NioSocketChannel channel) throws Exception {
                        //编码器,将要发送的消息转为ByteBuf
                        channel.pipeline().addLast(new StringEncoder());
                    }
                })
                //5. 连接到服务器
                .connect(new InetSocketAddress(8080));
        //阻塞方法,知道连接建立
        channelFuture.sync();
        //代表连接对象
        Channel channel = channelFuture.channel();
        //6. 向服务端发送数据
        channel.writeAndFlush("hello server");
    }
}
  • 处理方式1:sync方法同步阻塞等待建立连接 需

    //处理方式1:sync同步阻塞,等待建立连接
    Channel channel = channelFuture
            //阻塞方法,直到连接建立
            .sync()
            //代表连接对象
            .channel();
    channel.writeAndFlush("sync-msg...");
    System.out.println(channel);
    System.out.println("=====");
    

sync()方法作用。

如果没有sync,因为connect方法是异步非阻塞的,由main发起调用,真正执行connnect的是nio线程,连接是需要时间的,可能连接还没有建立成功,就去调用channel,显然此时是没有channel的,发送数据的方法是有channel调用的,肯定是发送不了的

  • 处理方式2:异步处理,由其他线程处理

    //2.处理方式2:通过addListener异步处理
    channelFuture.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture channelFuture) throws Exception {
            channelFuture.channel();
            channel.writeAndFlush("async-msg...");
        }
    });
    

closeFuture谅解

@Slf4j
public class CloseFutureClient {
    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup group = new NioEventLoopGroup();
        //1. 启动类
        ChannelFuture channelFuture = new Bootstrap()
                //2. 添加EventLoop
                .group(new NioEventLoopGroup())
                //3. 选择客户端channel实现
                .channel(NioSocketChannel.class)
                //4. 添加处理器
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    //在连接建立后被调用
                    protected void initChannel(NioSocketChannel channel) throws Exception {
                        //编码器,将要发送的消息转为ByteBuf
                        channel.pipeline().addLast(new StringEncoder());
                    }
                })
                //5. 连接到服务器
                .connect(new InetSocketAddress(8080));

        //处理方式1:sync同步阻塞,等待建立连接
        Channel channel = channelFuture
                //阻塞方法,直到连接建立
                .sync()
                //代表连接对象
                .channel();

        new Thread(() -> {
            Scanner scanner = new Scanner(System.in);
            while (true) {
                String s = scanner.nextLine();
                if ("q".equals(s)) {
                    //close是异步的,是由nio线程执行的
                    channel.close();
                    //关闭之后的其他操作,但是不能在这里善后处理,因为close方法异步的,有可能close还没执行,就走到了关闭之后的操作
                    //解决:使用closeFuture来处理,方式1:同步 方式2:异步
                    //log.info("关闭之后的操作");
                    break;
                }
                channel.writeAndFlush(s);
            }

        }, "input").start();

        ChannelFuture closeFuture = channel.closeFuture();

        //方式1:同步,是在main线程中处理
        /*closeFuture.sync();
        //关闭之后的操作
        log.info("同步关闭之后的操作");
        group.shutdownGracefully();*///优雅关闭客户端,停止java

        //方式2:异步,是在nio线程里处理
        closeFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                log.info("异步关闭之后的操作");
                group.shutdownGracefully();//优雅关闭客户端,停止java
            }
        });
    }
}

观察结果:

//方式1,看到是main
08:46:52.171 [main] INFO com.jpy.netty.c2.CloseFutureClient - 同步关闭之后的操作

//方式1看到思nio
08:53:35.956 [nioEventLoopGroup-2-1] INFO com.jpy.netty.c2.CloseFutureClient - 异步关闭之后的操作

注意点:

  • close方法是在nio线程中执行的,所以不能在close调用后直接进行善后处理,这样善后处理是在new Thread里执行,两个线程无法保障顺序
  • 方式1:同步,善后处理是在main中执行
  • 方式2:异步,善后处理是在nio线程中
posted @   jpy  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示