Netty學習之組件和設計

Netty學習之組件和設計

前言

前面我們簡單地介紹了Netty,然后學習了一個簡單的小例子,接下來我們來學習Netty的組件概要及組件之間的關系。

Channel,EventLoop,ChannelFuture

對于Netty來說,Channel、EventLoop、ChannelFuture三者的結(jié)合,就是Netty的網(wǎng)絡抽象

  • Channel代表的是Socket
  • EventLoop代表的是控制流,多線程以及并發(fā)
  • ChannelFuture代表的是異步通知

Channel接口

Netty中的Channel接口,減少了直接與Socket交互的復雜性,Netty中提供了眾多的預定義Channel

  • EmbeddedChannel
  • LocalServerChannel
  • NioDatagramChannel
  • NioSctpChannel
  • NioSocketChannel
  • NioServerSocketChannel

EventLoop接口

EventLoop定義了Netty處理事件的核心抽象。

Netty中的Channel、EventLoop、Thread以及EventLoopGroup的關系如下

  • 一個EventLoopGroup包含一個或者多個EventLoop
  • 一個EventLoop在其生命周期中綁定一個線程
  • 一個EventLoop處理的所有事件均由其對應的線程來處理(避免了同步需要加鎖的問題)
  • 一個Channel在其生命周期中注冊唯一一個EventLoop
  • 一個EventLoop可以同于處理一個或者多個Channel

具體的圖例如下所示(圖片來自《Netty In Action》)

Channel、EventLoop、EventLoopGroup的關系

ChannelFuture接口

在Netty中的所有操作都是異步的,因為所有的操作不太可能立即返回,所以我們需要有某個東西可以讓我們在需要的時候來獲取操作的結(jié)果,Netty中的ChannelFuture就是這個用途,通過其addListener()方法來注冊ChannelFutureListener實例,可以在操作完成之后獲得通知。

ChannelHandler,ChannelPipeline

如果說上面的三者是Netty的網(wǎng)絡抽象,那么ChannelHanlder、ChannelPipeline就是Netty中的數(shù)據(jù)控制流以及應用的處理邏輯了。

ChannelHandler接口

從開發(fā)者的角度來講,ChannelHandler是我們主要的操作對象,應用的操作邏輯都位于ChannelHandler中,ChannelHandler中的方法由網(wǎng)絡事件進行觸發(fā)和調(diào)用,ChannelHandler可以用于任何用途,比如講數(shù)據(jù)從一個格式轉(zhuǎn)換為另一種格式或者處理異常等。

有兩個主要的子接口,ChannelInboundHandler、ChannelOutboundHandler,用于處理兩種不同類型的數(shù)據(jù)(輸入的數(shù)據(jù)以及輸出的數(shù)據(jù))

同時,在Netty中提供了很多Adapter,用于提高開發(fā)者的開發(fā)效率,并且這些適配器會自動將事件傳遞給下一個處理器

  • ChannelHandlerAdapter
  • ChannelInboundHandlerAdapter
  • ChannelOutboundHanlderAdapter
  • ChannelDuplexHandlerAdapter

編解碼器

由于在網(wǎng)絡中發(fā)送的數(shù)據(jù)都是二進制格式,所以,當使用Netty進行網(wǎng)絡開發(fā)時,我們同樣需要對數(shù)據(jù)進行編碼和解碼

編碼用于將數(shù)據(jù)轉(zhuǎn)換成二進制格式

解碼用于將二進制格式轉(zhuǎn)換成我們需要的格式

Netty中提供了一些常用的編解碼器,這些編解碼器本質(zhì)上也是ChannelHandler,如ByteToMessageDecoder、MessageToByteEncoder

Channelpipeline接口

ChannelPipeline提供了將所有的ChannelHandler連接其他的容器,也就是說,在Netty中,所有的ChannelHandler通過ChannelPipeline串聯(lián)起來。同時,ChannelPipeline提供了在該鏈中進行事件傳播的方法。

ChannelPipeline通過下面的方式注冊ChannelHandler

  • ServerBootstrap注冊一個ChannelInitializer的實現(xiàn)類
  • 當ChannelInitializer.initChannel()被調(diào)用時,通過ChannelInitializer在ChannelPipeline注冊一系列的ChannelHandler
  • ChannelInitializer將自己從ChannelPipeline中移除

ChannelHandler根據(jù)初始化階段注冊的順序在ChannelPipeline中傳遞事件。

Netty中的事件可以通過每個方法中的ChannelHandlerContext來傳遞給下一個Handler,由于我們通常只關注某一個事件,所以Netty提供了ChannelInboundHandlerAdapter以及ChannelOutboundHandlerAdapter。

在Netty中有兩種方式可以發(fā)送數(shù)據(jù)

  • 直接通過Channel發(fā)送,會從頭到尾發(fā)送數(shù)據(jù)
  • 通過ChannelHandler綁定的ChannelHandlerContext進行發(fā)送,只會講數(shù)據(jù)傳遞給下一個ChannelHandler

Bootstrapping

Netty中的Bootstap類提供了應用的網(wǎng)絡層配置的容器

根據(jù)對象的不同,有兩種不同類型的bootstrap

  • ServerBootstrap,用于綁定本地端口,需要兩個EventLoopGroup(可以是同一個)
  • bootstrap,用于連接遠程主機及端口,只需要一個EventLoopGroup

一個服務器需要兩種不同類型的Channel,一個是用于存放一個單一的用于表示服務器自己監(jiān)聽的ServerChannel,一個用于維護所有已經(jīng)建立連接的Channel,也就是accept()操作之后的連接

總結(jié)

本小節(jié)我們主要學習Netty的核心組件概要及組件的關系,包括了Channel、EventLoop、EventLoopGroup、ChanneHandler、ChannelPipeline、Boostrap等,不同的組件有不同的功能,不同的組件之間又相互交互,共同構(gòu)成完整的Netty應用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容