Netty学习笔记(二) Channel和ChannelFuture

目录


Channel接口

API:Channel

Channel介绍

首先强调一点:NIO的ChannelNetty的Channel不是一个东西!
Netty重新设计了Channel接口,并且给予了很多不同的实现。Channel时Netty的网络抽象类,除了NIO中Channel所包含的网络I/O操作,主动建立/关闭连接,获取双方网络地址的功能外,还包含了Netty框架的功能,例如:获取Channel的EventLoop\Pipeline等。

  • Channel接口是能与一个网络套接字(或组件)进行I/0操作(读取\写入\连接\绑定)的纽带.
  • 通过Channel可以获取连接的状态(是否连接/是否打开),配置通道的参数(设置缓冲区大小等),进行I/O操作

Channel的基本方法

  • id():返回此通道的全局唯一标识符.
  • isActive():如果通道处于活动状态并连接,则返回true.
  • isOpen():如果通道打开并且可能稍后激活,则返回true.
  • isRegistered():如果通道注册了EventLoop,则返回true。
  • config():返回关于此通道的配置.
  • localAddress():返回此通道绑定的本地地址.
  • pipeline():返回分派的ChannelPipeline.
  • remoteAddress():返回此通道连接到的远程地址.
  • flush():请求通过ChannelOutboundInvoker将所有挂起的消息输出.
  • -

关于Channel的释放

当Channel完成工作后,需要调用ChannelOutboundInvoker.close()ChannelOutboundInvoker.close(ChannelPromise)释放所有资源.这样做是为了确保所有资源(文件句柄)都能够得到释放


ChannelFuture接口

API:ChannelFuture

ChannelFuture介绍

Future最早出现于JDK的java.util.concurrent.Future,它用于表示异步操作的结果.由于Netty的Future都是与异步I/O操作相关的,因此命名为ChannelFuture,代表它与Channel操作相关.

Netty API :
The result of an asynchronous Channel I/O operation.
All I/O operations in Netty are asynchronous. It means any I/O calls will return immediately with no guarantee that the requested I/O operation has been completed at the end of the call. Instead, you will be returned with a ChannelFuture instance which gives you the information about the result or status of the I/O operation.

由于Netty中的所有I / O操作都是异步的,因此Netty为了解决调用者如何获取异步操作结果的问题而专门设计了ChannelFuture接口.
因此,ChannelChannelFuture可以说形影不离的.

ChannelFuture的状态

Netty API :
A ChannelFuture is either uncompleted or completed. When an I/O operation begins, a new future object is created. The new future is uncompleted initially - it is neither succeeded, failed, nor cancelled because the I/O operation is not finished yet. If the I/O operation is finished either successfully, with failure, or by cancellation, the future is marked as completed with more specific information, such as the cause of the failure. Please note that even failure and cancellation belong to the completed state.

ChannelFuture有两种状态:未完成(uncompleted)完成(completed).
当令Channel开始一个I/O操作时,会创建一个新的ChannelFuture去异步完成操作.
被创建时的ChannelFuture处于uncompleted状态(非失败,非成功,非取消);一旦ChannelFuture完成I/O操作,ChannelFuture将处于completed状态,结果可能有三种:
1. 操作成功
2. 操作失败
3. 操作被取消(I/O操作被主动终止)

下图是 Netty API 中提供的ChannelFuture状态迁移图:

                                      +---------------------------+
                                      | Completed successfully    |
                                      +---------------------------+
                                 +---->      isDone() = true      |
 +--------------------------+    |    |   isSuccess() = true      |
 |        Uncompleted       |    |    +===========================+
 +--------------------------+    |    | Completed with failure    |
 |      isDone() = false    |    |    +---------------------------+
 |   isSuccess() = false    |----+---->      isDone() = true      |
 | isCancelled() = false    |    |    |       cause() = non-null  |
 |       cause() = null     |    |    +===========================+
 +--------------------------+    |    | Completed by cancellation |
                                 |    +---------------------------+
                                 +---->      isDone() = true      |
                                      | isCancelled() = true      |
                                      +---------------------------+

GenericFutureListener监听接口

虽然可以通过ChannelFutureget()方法获取异步操作的结果,但完成时间是无法预测的,若不设置超时时间则有可能导致线程长时间被阻塞;若是不能精确的设置超时时间则可能导致I/O操作中断.因此,Netty建议通过GenericFutureListener接口执行异步操作结束后的回调.

Netty API 中使用的GenericFutureListener示例代码:

 @Override
 public void channelRead(ChannelHandlerContext ctx, Object msg) {
     ChannelFuture future = ctx.channel().close();
     future.addListener(new ChannelFutureListener() {
         public void operationComplete(ChannelFuture future) {
             // Perform post-closure operation
             // ...
         }
     });
 }

另外,ChannelFuture允许添加一个或多个(移除一个或多个)GenericFutureListener监听接口,方法名:addListener(), addListeners(), removeListener(), removeListeners().

猜你喜欢

转载自blog.csdn.net/lgj123xj/article/details/78577945