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相关状态即可。