Netty中抽象的接口
主要有三种类型接口
- Channel ------ Socket
- EventLoop ------ 控制流、多线程和并发
- ChannelFuture ------ 异步通知
一、Channel接口
Channel的产生是为了降低网络传输变成的复杂性,它是传入传出数据的载体,可以打开或者关闭,连接或断开。可以当做它是Socket的升级,大大降低了直接与 Socket 进行操作的复杂性。
- EmbeddedChannel ----- Embedded传输,一般用于测试ChannelHandller
- LocalServerChannel ----- Local传输,在VM内部通过管道进行通信的本地传输
- NioDatagramChannel ----- UDP协议NIO传输
- NioSctpChannel ----- SCTP协议NIO传输(基于Session)
- NioSocketChannel ----- TCP协议NIO传输,使用Java提供的NIO作为基础,基于选择器的方式(重点)
二、EventLoop 接口
Channel 为Netty 网络操作抽象类,EventLoop 主要是为Channel 处理 I/O 操作,两者配合参与 I/O 操作。
下图是Channel、EventLoop、Thread、EventLoopGroup之间的关系(摘自《Netty In Action》)
Netty提供的EventLoop结合了JDK的并发编程和Channel的事件,能够帮助用户实现周期性任务调度任务,类层次如下
层次结构当一个连接到达时,Netty 就会注册一个 Channel,然后从 EventLoopGroup 中分配一个 EventLoop 绑定到这个Channel上,在该Channel的整个生命周期中都是有这个绑定的 EventLoop 来服务的。所以有如下约定俗成的关系(非常重要):
- 一个EventLoopGroup包含一个或多个EventLoop
- 一个EventLoop在其生命周期内只能和一个Thread绑定
- 由EventLoop处理的I/O事件都由它绑定的Thread处理
- 一个Channel在其生命周期内,只能注册于一个EventLoop
- 一个EventLoop可能被分配处理多个Channel。也就是EventLoop与Channel是1:n的关系
- 一个Channel上的所有ChannelHandler的事件由绑定的EventLoop中的I/O线程处理
- 不要阻塞Channel的I/O线程,可能会影响该EventLoop中其他Channel事件处理
source: Netty专栏-EventLoop和线程模型
三、 ChannelFuture 接口
Netty中所有的I/O操作都是异步的,该异步操作可能无法立即得到返回。Netty提供addListener()
方法注册回调函数——ChannelFutureListener
,当操作执行成功或者失败时,监听就会自动触发返回结果。
- 可以将ChannelFuture看作是将来要执行的操作的结果占位符,什么时候被执行,不知道。但肯定会被执行
- 属于同一个Channel的操作(回调函数)都被保证将按照注册的顺序执行。
比如有直接阻塞获取的方式:
/*绑定到端口,阻塞等待直到连接完成*/
ChannelFuture f = b.bind().sync();
异步监听的方式
serverBootstrap.bind(port).addListener(future -> {
if (future.isSuccess()) {
System.out.println(new Date() + ": 端口[" + port + "]绑定成功!");
} else {
System.err.println("端口[" + port + "]绑定失败!");
}
source: 【死磕Netty】-----Netty的核心组件)
网友评论