Netty中的Channel可以简单理解成连接通道。当有新连接创建时,也意味着有新Channel对象被创建。不同Channel实现与底层的传输处理方式相关,Netty提供了多种Channel实现,典型的有,
- NioSocketChannel
- NioServerSocketChannel
- OioSocketChannel
- OioServerSocketChannel
- EpollSocketChannel
- EpollServerSocketChannel
在Netty封装之后,不论底层用什么机制去处理,是用Java IO/NIO库实现还是和平台Native实现相关,都不再特别需要去关注。对于上层使用方来说,看到的就都只有Channel。
Channel接口
状态信息,
- isOpen(),是否开启
- isRegistered(),是否注册到EventLoop
- isActive(),是否活跃
- isWritable(),是否可写
Channel自身的生命周期内,状态变化路径大体是,
Registered -> Active -> Inactive -> Unregistered
配置信息,
- config(),Channel上可以配置底层传输的相关参数
地址信息,
- localAddress(),本地监听的地址
- remoteAddress(),远程访问的来源地址
关联的EventLoop,
- eventLoop(),每一个Channel只会与一个EventLoop相绑定
关联的ChannelPipeline,
- pipeline(),ChannelPipeline中的ChannelHandler是实际各种功能逻辑的实现者
Channel接口继承了AttributeMap接口,可以向Channel中进行Attribute的读写。Channel的I/O操作都是异步的,具体功能逻辑由一个或多个ChannelHandler组合而成,ChannelHandler可以获取到关联的Channel对象,因此不同ChannelHandler之间可以通过Channel上的Attribute进行一定意义上的数据传递。从这个视角来看,Channel也可以认为是多个ChannelHandler之间公共数据的一个暂存地。
在使用Netty去进行开发时,对于Channel,实际可能只是在应用启动之初进行选择,选择具体的Channel实现,而后就基本无需再特别关注了。
Channel创建过程
对于服务端来说,以Nio连接处理为例,
- 在ServerBootstrap中传入制定Channel类型,NioServerSocketChannel.class
- 在ServerBootstrap.bind调用过程中,会在基类AbstractBootstrap的initAndRegister方法中进行创建,具体是通过ReflectiveChannelFactory.newChannel根据Channel的类型进行反射创建。
- 在服务端启动之后,客户端连接进入时,则在NioServerSocketChannel.doReadMessages方法创建NioSocketChannel。
Channel创建完毕之后,在I/O处理过程中,会按照流程触发Register、Active操作,通过Channel相关接口可以获取到对应状态的变化结果。
一般来说,Channel的创建流程是不太需要去关心的。通过Channel接口在ChannelPipeline处理链路中去读取或改变Channel相关状态即可。