Netty学习摘记 —— Netty的组件和设计

本文参考

本篇文章是对《Netty In Action》一书第三章"Netty的组件和设计"的学习摘记,主要内容为Channel、EventLoop、ChannelFuture、ChannelHandler和ChannelPipeline等组件的详细介绍

Channel接口

A nexus to a network socket or a component which is capable of I/O operations such as read, write, connect, and bind.

Netty 的Channel接口所提供的 API,降低了直接使用 Socket 类的复杂性(下面仅列举一部分,如Unsafe内核模式的方法未列出)。此外,Channel 也是拥有许多预定义的、专门化实现的广泛类层次结构的根,如EmbeddedChannel、LocalServerChannel、NioDatagramChannel、NioSctpChannel、NioSocketChannel

ChannelId id() —— Returns the globally unique identifier of this Channel

EventLoop eventLoop() —— Return the EventLoop this Channel was registered to.

ChannelPipeline pipeline() —— Return the assigned ChannelPipeline.

ChannelConfig config() —— Returns the configuration of this channel.

boolean isRegistered() —— Returns true if the Channel is registered with an EventLoop.

boolean isOpen() —— Returns true if the Channel is open and may get active later

boolean isActive() —— Return true if the Channel is active and so connected.

SocketAddress localAddress() —— Returns the local address where this channel is bound to.

SocketAddress remoteAddress() —— Returns the remote address where this channel is connected to.

ChannelFuture closeFuture() —— Returns the ChannelFuture which will be notified when this channel is closed.

EventLoop接口

Will handle all the I/O operations for a Channel once registered.

EventLoop用于处理连接的生命周期中所发生的I/O事件,并且所有事件都将在它专有的Thread上被处理,因此消除了对于同步的需要

一个EventLoopGroup包含一个或者多个EventLoop

一个EventLoop在它的生命周期内只和一个Thread绑定(前面提到的选择器的概念)

一个Channel在它的生命周期内只注册于一个EventLoop(一个连接对应一个选择器)

一个EventLoop可能会被分配给一个或多个Channel(但一个选择器可能管理多个连接)

ChannelFuture接口

The result of an asynchronous Channel I/O operation.

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

例如上一篇文章中ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);无论服务端是否发送消息到客户端成功,发送操作结束后都会将该连接关闭

当然不只是通过addListener()方法来注册一个监听器,例如closeFuture方法也会返回一个ChannelFuture监听连接关闭

ChannelHandler接口

Handles an I/O event or intercepts an I/O operation, and forwards it to its next handler in its ChannelPipeline.

ChannelHandler充当了所有处理入站和出站数据的应用程序逻辑的容器,可专门用于几乎任何类型的动作,例如将数据从一种格式转换为另外一种格式,或者处理转换过程中所抛出的异常。其中,ChannelInboundHandler是一个经常使用的子接口,接收入站事件和数据,这些数据随后将会被我们的应用程序的业务逻辑所处理,例如要给连接的客户端发送响应时,可以从ChannelInboundHandler冲刷数据。因此,应用程序的业务逻辑通常驻留在一个或者多个ChannelInboundHandler中

ChannelPipeline接口

A list of ChannelHandles which handles or intercepts inbound events and outbound operations of a Channel

Each channel has its own pipeline and it is created automatically when a new channel is created.

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

ChannelHandler安装到ChannelPipeline中的过程:

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

在上篇文章中,我们通过ServerBootstrap的实例方法childHandler()添加ChannelHandler到ChannelPipeline上——b.childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(serverHandler); }});

出入站描述图(来自源码注释):

源码注释中举了一个ChannelHandler依次执行业务逻辑的例子,倘若在ServerBootstrap中注册了5个ChannelHandler

p.addLast("1", new InboundHandlerA());

p.addLast("2", new InboundHandlerB());

p.addLast("3", new OutboundHandlerA());

p.addLast("4", new OutboundHandlerB());

// 既实现了ChannelInboundHandler,又实现了ChannelOutboundHandler
p.addLast("5", new InboundOutboundHandlerX());

3 and 4 don't implement ChannelInboundHandler, and therefore the actual evaluation order of an inbound event will be: 1, 2, and 5

1 and 2 don't implement ChannelOutboundHandler, and therefore the actual evaluation order of a outbound event will be: 5, 4, and 3

但是使得事件流经 ChannelPipeline 是 ChannelHandler 的工作,它们是在应用程序的初始化或者引导阶段由addLast()方法安装。这些对象接收事件、执行它们所实现的处理逻辑,并将数据传递给链中的下一个ChannelHandler。它们的执行顺序是由它们被添加的顺序所决定的。可见,被我们称为ChannelPipeline的是这些ChannelHandler的编排顺序

 

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/kuluo/p/12618823.html