Netty之Channel相关

概述

为了快速开发可维护高性能的服务端客户端的异步、事件驱动的网络应用框架。

为什么不用Netty5

  1. 使用 ForkJoinPool,增加了代码的复杂度,但是对性能的改善却不明显。
  2. 使用AIO,但对性能的改善却不明显。为什么呢?
    1. 在Linux系统上,AIO的底层实现仍使用Epoll,没有很好实现AIO,处理回调结果速度跟不上处理需求,而且被JDK封装了一层不容易深度优化,因此在性能上没有明显的优势。
    2. AIO还有个缺点是接收数据需要预先分配缓存, 而不是NIO那种需要接收时才需要分配缓存, 所以对连接数量非常大但流量小的情况, 内存浪费很多。

Channel

在这里插入图片描述

它代表一个到实体(如一个硬件设备、一个文件、一个网络套接字或者一个能够执行一个或者多个不同的I/O操作的程序组件)的开放连接,如读操作和写操作
目前,可以把Channel 看作是传入(入站)或者传出(出站)数据的载体。因此,它可以被打开或者被关闭,连接或者断开连接。
在这里插入图片描述

Channel 的生命周期状态

ChannelUnregistered :Channel 已经被创建,但还未注册到EventLoop
ChannelRegistered :Channel 已经被注册到了EventLoop
ChannelActive :Channel 处于活动状态(已经连接到它的远程节点)。它现在可以接收和发送数据了
ChannelInactive :Channel 没有连接到远程节点
当这些状态发生改变时,将会生成对应的事件。这些事件将会被转发给ChannelPipeline 中的ChannelHandler,其可以随后对它们做出响应。

重要的几个 Channel方法

eventLoop: 返回分配给Channel 的EventLoop
pipeline: 返回分配给Channel 的ChannelPipeline
isActive: 如果Channel 是活动的,则返回true。活动的意义可能依赖于底层的传输。例如,一个Socket 传输一旦连接到了远程节点便是活动的,而一个Datagram 传输一旦被打开便是活动的。
localAddress: 返回本地的SokcetAddress
remoteAddress: 返回远程的SocketAddress
write: 将数据写到远程节点。这个数据将被传递给ChannelPipeline,并且排队直到它被冲刷
flush: 将之前已写的数据冲刷到底层传输,如一个Socket
writeAndFlush: 一个简便的方法,等同于调用write()并接着调用flush()

事件和ChannelHandler

Netty 使用不同的事件来通知我们状态的改变或者是操作的状态。这使得我们能够基于已经发生的事件来触发适当的动作。
Netty事件是按照它们与入站或出站数据流的相关性进行分类的。

  • 可能由入站数据或者相关的状态更改而触发的事件包括:
    连接已被激活或者连接失活;数据读取;用户事件;错误事件。
  • 出站事件是未来将会触发的某个动作的操作结果,这些动作包括:
    打开或者关闭到远程节点的连接;将数据写到或者冲刷到套接字。

每个事件都可以被分发给ChannelHandler 类中的某个用户实现的方法。
可以认为每个ChannelHandler 的实例都类似于一种为了响应特定事件而被执行的回调。
Netty 提供了大量预定义的可以开箱即用的ChannelHandler 实现,包括用于各种协议(如HTTP 和SSL/TLS)的ChannelHandler。

ChannelHandler

在这里插入图片描述
从应用程序开发人员的角度来看,Netty 最主要的组件是ChannelHandler,它充当了所有处理入站和出站数据的应用程序逻辑的容器。ChannelHandler 的方法是由网络事件触发的。事实上,ChannelHandler 可专门用于几乎任何类型的动作,例如将数据从一种格式转换为另外一种格式,例如各种编解码,或者处理转换过程中所抛出的异常。
举例来说,ChannelInboundHandler 是一个你将会经常实现的子接口。这种类型的ChannelHandler 接收入站事件和数据,这些数据随后将会被你的应用程序的业务逻辑所处理。当你要给连接的客户端发送响应时,也可以从ChannelInboundHandler 直接冲刷数据然后输出到对端。应用程序的业务逻辑通常实现在一个或者多个ChannelInboundHandler 中。
这种类型的ChannelHandler 接收入站事件和数据,这些数据随后将会被应用程序的业务逻辑所处理。

ChannelHandler 的生命周期

接口 ChannelHandler 定义的生命周期操作,在ChannelHandler被添加到ChannelPipeline 中或者被从ChannelPipeline 中移除时会调用这些操作。这些方法中的每一个都接受一个ChannelHandlerContext 参数。
在这里插入图片描述

  • handlerAdded 当把ChannelHandler 添加到ChannelPipeline 中时被调用
  • handlerRemoved 当从ChannelPipeline 中移除ChannelHandler 时被调用
  • exceptionCaught 当处理过程中在ChannelPipeline 中有错误产生时被调用

可以看到exceptionCaught已经被废除了,源码如下:
在这里插入图片描述
有源码可知,只有它的子接口ChannelInboundHandler有这个方法了。(其实ChannelHandlerAdapter实现了这个方法)

Netty 定义了下面两个重要的ChannelHandler 子接口:

  • ChannelInboundHandler——处理入站数据以及各种状态变化。
  • ChannelOutboundHandler——处理出站数据并且允许拦截所有的操作。

ChannelHandler有3个重要的子类型:编码器、解码器和 SimpleChannelInboundHandler< T >。

ChannelInboundHandler

下面列出了接口 ChannelInboundHandler 的生命周期方法。这些方法将会在数据被接收时或者与其对应的Channel 状态发生改变时被调用。正如我们前面所提到的,这些方法和 Channel 的生命周期密切相关。
在这里插入图片描述

  • channelRegistered:当Channel 已经注册到它的EventLoop 并且能够处理I/O 时被调用

  • channelUnregistered:当Channel 从它的EventLoop 注销并且无法处理任何I/O 时被调用

  • channelActive:当Channel 处于活动状态时被调用,Channel 已经连接/绑定并且已经就绪

  • channelInactive:当Channel 离开活动状态并且不再连接它的远程节点时被调用

  • channelRead:当从Channel 读取数据时被调用

  • channelReadComplete:当Channel上的一个读操作完成时被调用。如果是服务器,则读完一次TCP缓冲区的内容触发一次

  • channelWritabilityChanged:当Channel 的可写状态发生改变时被调用。可以通过调用Channel 的isWritable()方法来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值