从零开始学习Netty - 学习笔记 -Netty入门-ChannelFuture

5.2.2.Channel

Channel 的基本概念

在 Netty 中,Channel 是表示网络传输的开放连接的抽象。它提供了对不同种类网络传输的统一视图,比如 TCP 和 UDP。

Channel 的生命周期

Channel 的生命周期包括创建、激活、连接、读取、写入和关闭等阶段。Netty 中的 Channel 具有状态,根据不同的事件触发状态转换。

Channel channel = ...; // 获取 Channel 实例// 检查 Channel 是否打开
if (channel.isOpen()) {// 进行数据读取操作channel.read();
}// 关闭 Channel
channel.close();

Channel 的异步 I/O

Netty 中的 Channel 支持异步的 I/O 操作,这意味着可以在不阻塞线程的情况下进行网络通信。下面是一个简单的读取操作示例:

// 从 Channel 中读取数据
channel.read(new ChannelHandler() {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {// 处理读取到的数据ByteBuf buf = (ByteBuf) msg;System.out.println(buf.toString(Charset.defaultCharset()));buf.release(); // 释放资源}
});

ChannelHandler 和 ChannelPipeline

ChannelHandler 用于处理入站和出站的事件,而 ChannelPipeline 是一系列 ChannelHandler 的链,负责处理 Channel 传递的事件。

// 创建一个 ChannelInitializer 用于初始化 ChannelPipeline
ChannelInitializer<SocketChannel> initializer = new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) {ChannelPipeline pipeline = ch.pipeline();// 添加自定义的 ChannelHandler 到 ChannelPipeline 中pipeline.addLast("handler", new MyChannelHandler());}
};// 在 ServerBootstrap 中应用 ChannelInitializer
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(eventLoopGroup).channel(NioServerSocketChannel.class).childHandler(initializer); 

channel的主要作用

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

例如刚刚的客户端代码

		// 1.创建启动器try {new Bootstrap()// 2.指定线程模型 一个用于接收客户端连接,另一个用于处理客户端读写.group(new NioEventLoopGroup())// 3.选择客户端的Channel的实现.channel(NioSocketChannel.class)// 4.添加处理器.handler(new ChannelInitializer<NioSocketChannel>() {// 5.初始化处理器@Overrideprotected void initChannel(NioSocketChannel ch) throws Exception {// 6.添加具体的handler 客户端是需要一个编码器ch.pipeline().addLast(new StringEncoder());}})// 7.连接到服务器.connect(new InetSocketAddress("localhost", 8080)).sync() // 阻塞方法 知道连接建立.channel() // 代表客户端和服务端的连接// 8.向服务器发送数据.writeAndFlush("hello, world");} catch (InterruptedException e) {throw new RuntimeException(e);}
5.2.2.1.连接问题sync
			// 1.创建启动器try {ChannelFuture channelFuture = new Bootstrap().group(new NioEventLoopGroup()).channel(NioSocketChannel.class).handler(new ChannelInitializer<NioSocketChannel>() {@Overrideprotected void initChannel(NioSocketChannel ch) throws Exception {ch.pipeline().addLast(new StringEncoder());}})// 7.连接到服务器// connect方法是异步的,返回一个ChannelFuture(异步调用 就是不关心结果,直接返回)// main线程发起了调用,真正执行了connect是另外一个线程 nio线程.connect(new InetSocketAddress("localhost", 8080));// 7.1.同步等待连接成功 如果不调用sync()方法,main线程会继续往下执行,不会等待connect()方法的执行结果channelFuture.sync();// 7.2.获取连接对象 如果没有调用sync()方法,这里的channel此时还没有真正建立起连接Channel channel = channelFuture.channel(); // 连接对象logger.error("channel: {}", channel);// 8.向服务器发送数据channel.writeAndFlush("hello, world");} catch (Exception e) {throw new RuntimeException(e);}

image-20240226071218470

image-20240226071322706

5.2.2.2.处理结果

带有Future Promise 的类型,都是和异步方法配套使用的,用来正确处理结果的

  • 调用channelFuture.sync()处理同步结果,sync()主要是阻塞当前线程,直到nio线程连接建立完毕

  • 使用addListener(new ChannelFutureListener() )

    • 	// 使用addListener(回调对象)方法,可以在ChannelFuture执行完成后,再执行一些操作channelFuture.addListener(new ChannelFutureListener() {// 在NIO线程连接建立好后,会调用operationComplete方法@Overridepublic void operationComplete(ChannelFuture channelFuture) throws Exception {if (channelFuture.isSuccess()) {// 7.2.获取连接对象 如果没有调用sync()方法,这里的channel就会是nullChannel channel = channelFuture.channel(); // 连接对象logger.error("channel: {}", channel);// 8.向服务器发送数据channel.writeAndFlush("hello, world");} else {// 7.3.连接失败Throwable cause = channelFuture.cause();logger.error("connect failed: {}", cause);}}});
      
5.2.2.3.处理关闭

小需求 : 客户端 不断接收用于输入的信息,然后发送给客户端,当用户端输入q 退出 关闭channel

/**** @author 13723* @version 1.0* 2024/2/27 21:46*/
public class CloseFutureClient {private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());public static void main(String[] args) throws InterruptedException {ChannelFuture channelFuture = new Bootstrap().group(new NioEventLoopGroup()).channel(NioSocketChannel.class).handler(new ChannelInitializer<NioSocketChannel>() {@Overrideprotected void initChannel(NioSocketChannel ch) throws Exception {ch.pipeline().addLast(new StringEncoder());}}).connect(new InetSocketAddress("localhost", 8080));// 客户端 不断接收用于输入的信息,然后发送给客户端,当用户端输入q 退出// 建立建立Channel channel = channelFuture.sync().channel();logger.error("channel: {} ",channel);// 接收用户输入的需求new Thread(()->{Scanner scanner = new Scanner(System.in);while (true){String s = scanner.nextLine();if ("q".equals(s)){// 退出 关闭channel// 1s 后才真正的关闭channel.close();// 退出循环logger.error("处理关闭之后的操作!");break;}// 向服务器 发送数据channel.writeAndFlush(s);}},"input").start();}
}

在这里插入图片描述

在这里插入图片描述

  • 解决

    • 使用CloseFuture.sync()

      		// 关闭Channel// 获取closeFuture对象 1.同步受理关闭 2.异步处理关闭ChannelFuture closeFuture = channel.closeFuture();logger.error("wait close... ");closeFuture.sync();logger.error("处理关闭之后的操作!");
      

      在这里插入图片描述

    • 使用addListener(new ChannelFutureListener())

      		closeFuture.addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture channelFuture) throws Exception {logger.error("处理关闭之后的操作!");}});
      

      在这里插入图片描述

`

此时关闭,会会发现客户端并没有结束,因为线程虽然结束,但是NioEventLoopGroup 里面可能还有线程,这是时关闭,需要调

**shutdownGracefully()**方法

// 将NioEventLoopGroup提出来  
NioEventLoopGroup group = new NioEventLoopGroup();
ChannelFuture channelFuture = new Bootstrap().group(group)
.........// 然后在处理善后中调用 
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {logger.error("处理关闭之后的操作!");// 需要保证整个全部关闭group.shutdownGracefully();
}

在这里插入图片描述

5.2.2.4.为什么使用异步

思考下面这样的场景,4个医生给人看病,每个病人花费20分钟,而且医生看病的过程中,是以病人为单位的,一个病人看完了,才能看下一个病人,假设病人源源不断来,可以计算一天4个医生工作8小时,处理病人总数 4 * 8 * 3 = 96

在这里插入图片描述

经研究 发现 看病可以分为 四个步骤 经拆分后每个步骤仅需要五分钟

在这里插入图片描述

因此 可以做如下优化,只有一开始, 医生 2 3 4 需要分别等待 5 10 15分钟开能开始执行工作,但是只要后续病人源源不断的来,他们就能满负荷工作,并且处理病人的能力提高 到了, 4 * 8 * 12 整个效率 是原先的 4 倍

(满负载情况下)第一个医生 只挂号,一个号五分钟,那么 一个小时 可以处理 12个,之前一个医生从头到尾只能看一个病人,那么一个小时只能看3个

在这里插入图片描述

  • 单线程没法异步提高效率,必须配合多线程,多核心cpu才能发挥异步的优势
  • 异步并没有缩短响应时间,反而有所增加(提高的是吞吐量,单位时间内能够处理请求的速度)
  • 合理任务的拆分,也是利用异步的关键

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

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

相关文章

创业者必读:跨境ERP搭建实用技巧大揭秘

随着全球化进程不断加快&#xff0c;跨境电商市场蓬勃发展&#xff0c;吸引着越来越多的创业者涉足。然而&#xff0c;跨境业务的复杂性和多样性也给企业管理带来了挑战。在这样的背景下&#xff0c;打造一个适合企业实际需求的ERP系统变得至关重要。ERP定制为跨境业务量身定制…

nvm下载node指定版本后npm不存在

一&#xff0c;项目背景 接手一个老的项目&#xff0c;需要使用旧的node版本&#xff0c;使用nvm下载12.11.0版本后发现npm命令不存在。 二&#xff0c;原因 查找资料发现是8.11以上版本的node版本对应的npm都没法自动安装&#xff0c;需要自己到npm官网( https://registry.…

Flutter(三):Stack、Positioned、屏幕相关尺寸、Navigator路由跳转

页面尺寸 通知栏高度&#xff1a;MediaQuery.of(context).padding.top顶部导航高度&#xff1a;kToolbarHeight底部导航高度&#xff1a;kBottomNavigationBarHeight屏幕宽&#xff1a;MediaQuery.of(context).size.width屏幕高&#xff1a;MediaQuery.of(context).size.height…

南京师范大学计电院数据结构课设——排序算法

1 排序算法 1.1 题目要求 编程实现希尔、快速、堆排序、归并排序算法。要求首先随机产生10000个数据存入磁盘文件&#xff0c;然后读入数据文件&#xff0c;分别采用不同的排序方法进行排序并将结果存入文件中。 1.2 算法思想描述 1.2.1 随机数生成 当需要生成一系列随机数…

ChatGPT 正测试Android屏幕小组件;联想ThinkBook 推出透明笔记本电脑

▶ ChatGPT 测试屏幕小组件 近日 ChatGPT 正在测试 Android 平台上的屏幕小组件&#xff0c;类似于手机中的悬浮窗&#xff0c;按住 Android 手机主屏幕上的空白位置就可以调出 ChatGPT 的部件菜单。 菜单中提供了许多选项&#xff0c;包括文本、语音和视频查询的快捷方式&…

微信小程序引入Vant插件

Vant官网&#xff1a;Vant Weapp - 轻量、可靠的小程序 UI 组件库 先查看官网的版本 新建一个package.json页面&#xff0c;代码写上&#xff1a;&#xff08;我先执行的npm安装没出package页面&#xff0c;所以先自己创建了一个才正常&#xff09; {"dependencies"…

LeetCode 刷题 [C++] 第54题.螺旋矩阵

题目描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 题目分析 根据题意可知&#xff0c;我们不需要记录已经走过的路径&#xff0c;只需要通过调整矩阵的上下左右边界即可完成任务&#xff1b;首先创建出矩阵…

NerfStudio安装及第一个场景重建

NerfStudio文档是写在windows和linux上安装&#xff0c;本文记录Linux安装的过程&#xff0c;且我的cuda是11.7 创建环境 conda create --name nerfstudio -y python3.8 conda activate nerfstudio python -m pip install --upgrade pip Pytorch要求2.0.1之后的,文档推荐cud…

深度学习 精选笔记(5)多层感知机

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

LeetCode 热题 100 | 图论(上)

目录 1 200. 岛屿数量 2 994. 腐烂的橘子 2.1 智障遍历法 2.2 仿层序遍历法 菜鸟做题&#xff0c;语言是 C 1 200. 岛屿数量 解题思路&#xff1a; 遍历二维数组&#xff0c;寻找 “1”&#xff08;若找到则岛屿数量 1&#xff09;寻找与当前 “1” 直接或间接连接在…

【PHP】Workerman开源应用容器的GatewayWorker 与 iOS-OC对接

Workerman 开源高性能PHP应用容器 workerman是一款开源高性能PHP应用容器,它大大突破了传统PHP应用范围,被广泛的用于互联网、即时通讯、APP开发、硬件通讯、智能家居、物联网等领域的开发。 PHPSocket.io PHP版本的socket.io,具有良好的客户端兼容性,常用于即时通讯领域…

uniapp android 原生插件开发-测试流程

前言 最近公司要求研究一下 uniapp 的 android 原生插件的开发&#xff0c;为以后的工作做准备。这篇文章记录一下自己的学习过程&#xff0c;也帮助一下有同样需求的同学们 : ) 一、下载安装Hbuilder X , Android studio&#xff08;相关的安装配置过程网上有很多&#xff0c;…

git忽略某些文件(夹)更改方法

概述 在项目中,常有需要忽略的文件、文件夹提交到代码仓库中,在此做个笔录。 一、在项目根目录内新建文本文件,并重命名为.gitignore,该文件语法如下 # 以#开始的行,被视为注释. # 忽略掉所有文件名是 a.txt的文件. a.txt # 忽略所有生成的 java文件, *.java # a.j…

C#,数组数据波形排序(Sort in Wave Form)的朴素算法与源代码

1 波形排序 所谓“波形排序”就是一大一小。 将n个身高互不相同的人排成一行 ,对于每个人 ,要求他要么比相邻的人均高 ,要么比相邻的人均矮 ,问共有多少种排法 ,这一问题称为波形排列问题。 2 源程序 using System; using System.Collections; using System.Collections.Gen…

新能源汽车交流充电桩开发介绍

概述 最些年&#xff0c;随着新能源行业迅猛发展&#xff0c;充电桩市场缺口非常大&#xff0c;越来越多的公司和人涌入这个行业。充电桩作为新能源行业解决新能源汽车续航的存在&#xff0c;竞争也非常大。除了一些初创公司外&#xff0c;从行业开始国企央企就参与其中&#x…

【MySQL | 第一篇】undo log、redo log、bin log三者之间的区分?

undo log、redo log、bin log三者之间的区分&#xff1f; 从 产生的时间点、日志内容、用途 三方面展开论述即可 1.undo log——撤销日志 时间点&#xff1a;事务开始之前产生&#xff0c;根据当前版本的数据生成一个undo log&#xff0c;也保存在事务开始之前 作用&#xf…

分享three.js和cannon.js构建Web 3D场景

使用 three.js&#xff0c;您不再需要花哨的游戏PC或控制台来显示逼真的3D图形。 您甚至不需要下载特殊的应用程序。现在每个人都可以使用智能手机和网络浏览器体验令人惊叹的3D应用程序。 这个惊人的库和充满活力的社区是您在浏览器、笔记本电脑、平板电脑或智能手机上创建游…

《成才之路》是什么级别的期刊?是知网学术期刊吗?能评职称吗?

问题解答 问&#xff1a;《成才之路》是什么级别刊物&#xff1f; 答&#xff1a;省级 问&#xff1a;《成才之路》是知网学术期刊吗&#xff1f; 答&#xff1a;是的&#xff0c;第二批学术目录内期刊 问&#xff1a;《成才之路》是正规期刊吗&#xff1f; 答&#xff1a…

使用ffmpeg压缩视频

一、到ffmpeg官网下载文件包&#xff1a; Download FFmpeg 下载后找到 bin 下的3个exe文件&#xff0c;复制到自己本机的某个目录下, 如&#xff1a; 二、使用命令行压缩&#xff1a; ffmpeg -i input.mp4 -c:v libx265 -crf 28 -y output.mp4 这条命令使用 FFmpeg 工具对输…

OpenCV与AI深度学习 | 使用YOLOv8做目标检测、实例分割和图像分类(包含实例操作代码)

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;使用YOLOv8做目标检测、实例分割和图像分类 0 导 读 本文主要介绍YOLOv8及使用它做目标检测、实例分割和图像分类演示&#xff0c;仅供参考。…