Netty學習筆記(二) Channel和ChannelFuture
目錄
Channel介面
Channel介紹
首先強調一點:NIO的Channel
與Netty的Channel
不是一個東西!
Netty重新設計了Channel介面,並且給予了很多不同的實現。Channel時Netty的網路抽象類,除了NIO中Channel所包含的網路I/O操作,主動建立/關閉連線,獲取雙方網路地址的功能外,還包含了Netty框架的功能,例如:獲取Channel的EventLoop\Pipeline等。
- Channel介面是能與一個網路套接字(或元件)進行I/0操作(讀取\寫入\連線\繫結)的紐帶.
- 通過Channel可以獲取連線的狀態(是否連線/是否開啟),配置通道的引數
Channel的基本方法
- id():返回此通道的全域性唯一識別符號.
- isActive():如果通道處於活動狀態並連線,則返回true.
- isOpen():如果通道開啟並且可能稍後啟用,則返回true.
- isRegistered():如果通道註冊了EventLoop,則返回true。
- config():返回關於此通道的配置.
- localAddress():返回此通道繫結的本地地址.
- pipeline():返回分派的ChannelPipeline.
- remoteAddress():返回此通道連線到的遠端地址.
- flush():請求通過ChannelOutboundInvoker將所有掛起的訊息輸出.
關於Channel的釋放
當Channel完成工作後,需要呼叫ChannelOutboundInvoker.close()
或ChannelOutboundInvoker.close(ChannelPromise)
釋放所有資源.這樣做是為了確保所有資源(檔案控制代碼)都能夠得到釋放
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介面.
因此,Channel與ChannelFuture可以說形影不離的.
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監聽介面
雖然可以通過ChannelFuture的get()
方法獲取非同步操作的結果,但完成時間是無法預測的,若不設定超時時間則有可能導致執行緒長時間被阻塞;若是不能精確的設定超時時間則可能導致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()
.