netty入门-4 Channel与ChannelFuture

news2024/11/14 20:53:25

Channel

基本类似于NIO中的Channel概念。作为读写数据的通道。
常见方法

  • close() 可以用来关闭 channel
  • closeFuture() 用来处理 channel 的关闭
    • sync 方法作用是同步等待 channel 关闭
    • addListener 方法是异步等待 channel 关闭
  • pipeline() 方法添加处理器
  • write() 方法将数据写入
  • writeAndFlush() 方法将数据写入并刷出

这些方法其中大多与NIO中的Channel一致。使用起来大同小异。

这里closeFuture是一个异步处理关闭结果的类。
如果我们直接使用close()方法关闭通道,它会异步的去进行关闭,直接执行后面的代码。
所以如果有操作希望在通道完全关闭后再进行就需要用这个closeFuture了。下面会介绍怎么用。

write方法,不一定立即发出消息。因为netty有一个缓冲机制,一般会等到消息积累一定大小再发送。所以writeAndFlush()方法的意义在于,不仅写到缓冲区,还要立即通过网络发送出去。

ChannelFuture

这个 ChannelFuture 是与Channel息息相关的类。
同时对于Future,学过一些并发编程的应该了解,是我们用来获取异步处理结果的类(同步阻塞等待)。
而这里的 ChannelFuture 类似于Future,它的目的是阻塞等待,或者添加异步回调来处理结果。
使用方法见下。
先看我们这段示例代码
在这里插入图片描述
我们观察截图中的代码。
可以看到用Bootstrap创建客户端时,链式调用到connect方法时返回的就是一个ChannelFuture对象。接下来的sync()channel方法自然就是ChannelFuture的方法了。顾名思义,sync()是同步等待结果,channel()是获取对应Channel。然后我们用拿到的Channel去做读写操作。

那么我们connect()方法为什么不能直接拿到Channel,而是要加这么一层ChannelFuture呢?
因为connect()是网络操作,需要一定时间才能完成连接的建立,完成后才能返回对应连接的ChannelNetty所有操作都是异步的)。所以这个ChannelFuture就是用来等待连接结果的,就是一个异步结果的接收类,当connect()操作没完成时去获取Channel是获取不到的,所以调用sync等待异步操作connect()完成再调用channel()获取Channel

注意这里使用ChannelFuturesync的作用是让我们得线程对异步操作同步等待。
本段开头提到还有另一种方法处理异步结果,就是设置回调。即调用addListener方法给ChannelFuture添加一个监听器,并写好我们希望异步操作结束后进行什么操作,在异步操作结束后会触发监听器中我们写好的回调函数。
例子如下:

ChannelFuture channelFuture = new Bootstrap()
    .group(new NioEventLoopGroup())
    .channel(NioSocketChannel.class)
    .handler(new ChannelInitializer<Channel>() {
        @Override
        protected void initChannel(Channel ch) {
            ch.pipeline().addLast(new StringEncoder());
        }
    })
    .connect("127.0.0.1", 8080);
System.out.println(channelFuture.channel()); // 1
channelFuture.addListener((ChannelFutureListener) future -> {
    System.out.println(future.channel()); // 2
});

这里的lambda表达式实际上是重写的ChannelFutureListener类中的operationComplete方法,这个方法会在异步操作完成后被调用,而它由我们重写,所以我们通过这种回调的方式来进行异步方法结果的处理。(具体怎么调用监听器里的方法不太清楚,需要看源码,估计实现应该不难,就是在操作结束后调一个方法。这里仅学习用法。后续我再去学习netty的源码)

同时Netty中除了connect的其他IO操作如writebindread等操作也是异步的,也可以用ChannelFuture来处理。

CloseFuture

ChannelFuture处理connectwrite等操作。
CloseFuture则是特殊的ChannelFuture。专门处理close操作

示例程序

@Slf4j
public class CloseFutureClient {
    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup group new NioEventLoopGroup();
        ChannelFuture channelFuture = new Bootstrap()
                .group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override // 在连接建立后被调用
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
                        ch.pipeline().addLast(new StringEncoder());
                    }
                })
                .connect(new InetSocketAddress("localhost", 8080));
        Channel channel = channelFuture.sync().channel();
        log.debug("{}", channel);
        new Thread(()->{
            Scanner scanner = new Scanner(System.in);
            while (true) {
                String line = scanner.nextLine();
                if ("q".equals(line)) {
                    channel.close(); // close 异步操作 1s 之后
//                    log.debug("处理关闭之后的操作"); //此处不能做close操作完成后的处理,因为close是异步的,close没完成就会直接执行后面代码
                    break;
                }
                channel.writeAndFlush(line);
            }
        }, "input").start();

        // 获取 CloseFuture 对象, 1) 同步处理关闭, 2) 异步处理关闭
        ChannelFuture closeFuture = channel.closeFuture();
        /*log.debug("waiting close...");
        closeFuture.sync();
        log.debug("处理关闭之后的操作");*/
        closeFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                log.debug("处理关闭之后的操作");
                group.shutdownGracefully();
            }
        });
    }
}

结语

老师这部分是Channel与ChannelFuture一起讲解使用,仅仅讲述了最基本的方法。

对于ChannelFuture的状态,偏内部机制的部分没有讲解。
且在紧接着的下部分讲解Future与Promise时也没有说到。

所以我打算这篇先按课程中的讲解,把最基本的使用摆上来。在下一篇对比分析Netty的Future与Promise时再考虑是否扩展偏底层的部分(我是初学者,扩展还需要自己看书或者找文章看,虽然已经看过了,但是写出来不免还是要费些时间精力的)。

感谢阅读,欢迎批评指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1946330.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Stable Diffusion基本原理通俗讲解

Stable Diffusion是一种基于深度学习的图像生成技术&#xff0c;它属于生成对抗网络&#xff08;GANs&#xff09;的一种。简单来说&#xff0c;Stable Diffusion通过训练一个生成器&#xff08;Generator&#xff09;和一个判别器&#xff08;Discriminator&#xff09;&#…

算法力扣刷题记录 五十八【701.二叉搜索树中的插入操作】

前言 本文是二叉搜索树操作。 二叉树篇继续。 一、题目阅读 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节…

【常见开源库的二次开发】基于openssl的加密与解密——SHA算法源码解析(六)

目录 一、SHA-1算法分析&#xff1a; 1.1 Merkle Tree可信树 1.2 源码实现&#xff1a; 1.3 哈希计算功能 1.4 两种算法的区别&#xff1a; 1.4.1 目的 1.4.2 实现机制 1.4.3 输出 1.4.4 应用场景&#xff1a; 1.4 运行演示&#xff1a; 二、SHA-2算法分析&#xff1a; 2.1哈…

【ESP32S3学习笔记】与有人AP520X路由器连接失败的问题

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 项目上新换了个路由器&#xff0c;结果发现ESP32模组连接不上&#xff0c;其他的路由器都正常。 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 对比log发现有问题的时候&#x…

智慧大棚数据库版

创建一个SMartBigHouse数据库 在数据库创建一个表用来存储数据 这边将id设为主键并将标识增量设为1 搭建Winfrom 搭建历史查询界面 串口数据&#xff0c;(这边是用的一个虚拟的串口工具&#xff0c;需要的话私) ModbusSerialMaster master;DataPointCollection wenduValues; //…

Win10使用VS Code远程连接Ubuntu服务器时遇到SSH公钥错误的解决方案

在使用Windows 10上的Visual Studio Code&#xff08;VS Code&#xff09;远程连接Ubuntu 20.04服务器时&#xff0c;遇到了以下错误&#xff1a; 错误的原因 这个错误消息表明&#xff0c;SSH 客户端检测到远程主机的 ECDSA 公钥已更改。可能是由于以下原因之一&#xff1a…

python—NumPy的基础(2)

文章目录 一维数组索引和切片一维数组索引和切片的使用一维数组负索引和切片的使用 二维数组的索引和切片索引直接获取使用坐标获取数组[x,y]二维数组负索引的使用切片数组的复制 改变数组的维度改变数组的维度 数组的拼接列表的拼接一维数组的拼接二维数组的拼接vstack 与hsta…

el-image预览图片点击遮盖处关闭预览

预览关闭按钮不明显 解决方式&#xff1a; 1.修改按钮样式明显点&#xff1a; //el-image 添加自定义类名&#xff0c;下文【test-image】代指 .test-image .el-icon-circle-close{ color:#fff; font-size:20px; ...改成很明显的样式 }2.使用事件监听&#xff0c;监听当前遮…

第十一章 数据结构

第十一章 数据结构 11.1 数组 数组是元素的顺序集合&#xff0c;通常这些元素具有相同的数据类型 索引表示元素在数组中的顺序号&#xff0c;顺序号从数组开始处计数 数组元素通过索引被独立给出了地址&#xff0c;数组整体上有一个名称&#xff0c;但每个元素利用数组的的…

TCP网络socket编程(面向连接)

Tcp面向链接、面向字节流和文件的读写非常类似&#xff08;&#xff09;&#xff1a;客户端创建套接字主动建立连接&#xff0c;服务器监听套接字一直等待连接的到来&#xff0c;监听到一个&#xff0c;就创建一个新的套接字用于IO 服务器&#xff1a; 创建套接字&#xff1a…

区块链和数据要素融合的价值及应用

一、数据要素面临的关键障碍 在构建数据要素基石的过程中&#xff0c;首要任务是明确并解决产权架构的难题&#xff0c;特别是使用权的确立与流转机制的顺畅&#xff0c;此乃数字经济蓬勃发展的命脉所在。一个高效的数据流转体系对于激发数据潜能、加速经济发展及优化数据资源…

TreeSelect增加可筛选功能

TreeSelect官方可筛选示例 <template><el-tree-selectv-model"value":data"data"filterablestyle"width: 240px"/><el-divider /><el-divider />filter node method:<el-tree-selectv-model"value":data&q…

使用torch_pruning对YOLOv8进行剪枝(新版、detect、segment)

torch_pruning库介绍 在结构修剪中&#xff0c;**Group被定义为深度网络中最小的可移除单元。**每个组由多个相互依赖的层组成&#xff0c;需要同时修剪这些层以保持最终结构的完整性。然而&#xff0c;深度网络通常表现出层与层之间错综复杂的依赖关系&#xff0c;这对结构修剪…

[大牛直播SDK]Windows平台RTMP直播推送模块功能设计

技术优势 全自研框架&#xff0c;易于扩展&#xff0c;自适应算法让延迟更低、采集编码传输效率更高&#xff1b;所有功能以SDK接口形式提供&#xff0c;所有状态&#xff0c;均有event回调&#xff0c;完美支持断网自动重连&#xff1b;SDK模块化&#xff0c;可和大牛直播播放…

DBeaver Ultimate 22.1.0 连接数据库(MySQL+Mongo+Clickhouse)

前言 继续书接上文 Docker Compose V2 安装常用数据库MySQL+Mongo,部署安装好之后我本来是找了一个web端的在线连接数据库的工具,但是使用过程中并不丝滑,最终还是选择了使用 DBeaver ,然后发现 mongo 还需要许可,又折腾整理了半下午,终于大功告成。 DBeaver 版本及说明…

SpringBoot集成Sharding-JDBC实现分库分表

本文已收录于专栏 《中间件合集》 目录 版本介绍背景介绍拆分方式集成并测试1.引入依赖2.创建库和表3.pom文件配置3.编写测试类Entity层Mapper接口MapperXML文件测试类 4.运行结果 自定义分片规则定义分片类编写pom文件 总结提升 版本介绍 SpringBoot的版本是&#xff1a; 2.3.…

SpringBoot上传超大文件导致Cannot read more than 2,147,483,647 into a byte array,问题解决办法

问题描述 报错: java.lang.IllegalArgumentException: Cannot read more than 2,147,483,647 into a byte array at org.apache.commons.io.IOUtils.lambda$toByteArray$0(IOUtils.java:2403) ~[commons-io-2.11.0.jar:2.11.0] at org.apache.commons.io.output.Thre…

python每日学习12:pandas库的用法(1)

python每日学习12&#xff1a;pandas库的用法&#xff08;1&#xff09; 安装 pip install pandas设定系统环境 import pandas as pd #设定自由列表输出最多为 10 行 pd.options.display.max_rows 10 # 显示当前 Pandas 版本号 pd.__version__进入jupyter notebook 页面 在终端…

氧气传感器在汽车制氧检测中的应用

在当今汽车工业中&#xff0c;技术的快速发展不仅带来了驾驶安全性和舒适性的显著提升&#xff0c;还为车辆增加了各种智能功能&#xff0c;以应对不同的驾驶环境和需求。氧气传感器作为一种关键的技术装置&#xff0c;在汽车制氧检测系统中的应用&#xff0c;尤其是针对疲劳驾…

困于数字化泥潭的软件公司|专题报告集

数字化专题报告集链接&#xff1a;https://tecdat.cn/?p36964 在探讨企业数字化转型的进程中&#xff0c;软件公司无疑扮演着举足轻重的角色。它们不仅是技术创新的驱动力&#xff0c;更是连接管理与技术的桥梁。然而&#xff0c;正如许多观察家所指出的那样&#xff0c;软件…