Netty 在一個(gè)引導(dǎo)中添加多個(gè) ChannelHandler

2018-08-03 16:30 更新

在所有的例子代碼中,我們在引導(dǎo)過程中通過 handler() 或childHandler() 都只添加了一個(gè) ChannelHandler 實(shí)例,對于簡單的程序可能足夠,但是對于復(fù)雜的程序則無法滿足需求。例如,某個(gè)程序必須支持多個(gè)協(xié)議,如 HTTP、WebSocket。若在一個(gè) ChannelHandle r中處理這些協(xié)議將導(dǎo)致一個(gè)龐大而復(fù)雜的 ChannelHandler。Netty 通過添加多個(gè) ChannelHandler,從而使每個(gè) ChannelHandler 分工明確,結(jié)構(gòu)清晰。

Netty 的一個(gè)優(yōu)勢是可以在 ChannelPipeline 中堆疊很多ChannelHandler 并且可以最大程度的重用代碼。如何添加多個(gè)ChannelHandler 呢?Netty 提供 ChannelInitializer 抽象類用來初始化 ChannelPipeline 中的 ChannelHandler。ChannelInitializer是一個(gè)特殊的 ChannelHandler,通道被注冊到 EventLoop 后就會調(diào)用ChannelInitializer,并允許將 ChannelHandler 添加到CHannelPipeline;完成初始化通道后,這個(gè)特殊的 ChannelHandler 初始化器會從 ChannelPipeline 中自動刪除。

聽起來很復(fù)雜,其實(shí)很簡單,看下面代碼:

Listing 9.6 Bootstrap and using ChannelInitializer

ServerBootstrap bootstrap = new ServerBootstrap();//1
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())  //2
    .channel(NioServerSocketChannel.class)  //3
    .childHandler(new ChannelInitializerImpl()); //4
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));  //5
future.sync();


final class ChannelInitializerImpl extends ChannelInitializer<Channel> {  //6
    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline(); //7
        pipeline.addLast(new HttpClientCodec());
        pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE));

    }
}
  1. 創(chuàng)建一個(gè)新的 ServerBootstrap 來創(chuàng)建和綁定新的 Channel
  2. 指定 EventLoopGroups 從 ServerChannel 和接收到的管道來注冊并獲取 EventLoops
  3. 指定 Channel 類來使用
  4. 設(shè)置處理器用于處理接收到的管道的 I/O 和數(shù)據(jù)
  5. 通過配置的引導(dǎo)來綁定管道
  6. ChannelInitializer 負(fù)責(zé)設(shè)置 ChannelPipeline
  7. 實(shí)現(xiàn) initChannel() 來添加需要的處理器到 ChannelPipeline。一旦完成了這方法 ChannelInitializer 將會從 ChannelPipeline 刪除自身。

通過 ChannelInitializer, Netty 允許你添加你程序所需的多個(gè) ChannelHandler 到 ChannelPipeline


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號