Netty-组件和设计

Channel——Socket
EventLoop——控制流、多线程处理和并发
ChannelFuture——异步通知

Channel接口

基本的I/O操作(bind、connect、read和write)依赖于底层的网络传输提供的API。

  • EmbededChannel
  • LocalServerChannel
  • NioDatagramChannel
  • NioSctpChannel
  • NioSocketChannel

EventLoop接口

  • 一个EventLoopGrroup包含一个或者多个EventLoop;
  • 一个EventLoop在它的生命周期内只和一个Thread绑定
  • 所有由EventLoop处理的I/O事件都将在它专有的Thread上被处理;
  • 一个Channel在它的生命周期内注册于一个EeventLoop;
  • 一个EventLoop可能会被分配给一个或者多个Channel

一个给定的Channel的I/O操作都是由相同的Thread执行的,实际上是消除了对于同步的需求。

点击加载

ChannelFuture接口

Netty的所有操作都是异步的。因为一个操作可能不会立即返回,所以我们需要一种用于在之后的某个时间点确定其返回结果的方法。为此,Netty提供ChannelFuture接口,其addListener()注册了一个ChannelFutureListener,以便在某个操作完成时候得到通知。

事件及其流水线

ChannelHandler和ChannelPipeline

ChannelHandler接口

ChannelHandler充当了所有处理入站和出站数据的应用程序逻辑的容器。该方法是由网络事件触发的。事实上,ChannelHandler可专门用于几乎任何类型的动作,例如将数据从一种格式转换为另一种格式,或者处理转换过程中所抛出的异常。

ChannelPipeline接口

ChannelPipeline提供了ChannelHandler链的容器,并定义了用于在该链上传播入站和出站事件流的API。当Channel被创建时,它会被自动分配到它专属的ChannelPipeline。
ChannelHandler安装到ChannelPipeline中的过程如下:

  1. 一个ChannelInitializer的实现被注册到了Bootstrap/ServerBootstrap中;
  2. 当ChannelInitializer.initChannel()方法被调用时,ChannelInitializer将在ChannelPipeline中安装一组自定义的ChannelHandler;
  3. ChannelInitializer将它自己从ChannelPipeline中移除。

Netty能区分扩展自ChannelHandler的ChannelInboundHandler和ChannelOutboundHandler,并确保数据只会在具有相同定向类型的两个ChannelHandler之间传递。

ChannelHandlerContext

通过使用作为参数传递到每个方法的ChannelHandlerContext,事件可以被传递给当前ChannelHandler链中的下一个ChannelHandler。通过调用ChannelHandlerContext上对应的方法,每个都提供了简单地将事件传递给下一个ChannelHandler的方法的实现。

ChannelHandler的适配器类

Netty以适配器类的形式提供了大量默认的ChannelHandler实现,其旨在简化应用程序处理逻辑的开发过程。
有一些适配器类可以将自定义的ChannelHandler所需要的努力降到最低限度,因为它们提供了定义对应接口中所有方法的默认实现。
下面这些是编写自定义ChannelHandler时经常会用到的适配器类:

  • ChannelHandlerAdapter
  • ChannelInboundHandlerAdapter
  • ChannelOutboundHandlerAdapter
  • ChannelDuplexHandler

抽象类SimpleChannelInboundHandler< T>

最常见的情况,应用程序会利用一个ChannelHandler来接收解码消息,并对该数据应用业务逻辑。要创建一个这样的ChannelHandler,你只需要扩展基类SimpleChannelInboundHanlder< T>。其中最重要的方法是channelRead0(ChannelHandlerContext, ByteBuf),除了要求不阻塞于当前I/O线程之外,其他具体实现都可以。