Netty4.x中文教程系列(六) 從頭開始Bootstrap
其實自從中文教程系列(五)一直不知道自己到底想些什么。加上忙着工作上出現了一些問題。本來想就這么放棄維護了。沒想到有朋友和我說百度搜索推薦了我的文章。瞬間有點小激動啊。決定自己要把這個教程系列完善下去。這里誠摯的想支持我的盆友們道歉。真的是讓你們失望了。我居然有想放棄的這種喪心病狂的念頭。以后絕對不會了。
其實伴隨着對Netty的逐步深入學習。感覺自己對netty的了解仍然有所欠缺。加上筆者語文課是美術老師教的。所以。。說多了都是淚啊。~~o(>_<)o ~~
下面開始正文:
縱覽Netty框架的包結構,不難看出。其實Netty是有五大模塊組成。
-
Bootstrap負責啟動引導
-
Buffer是Netty自己封裝的緩存器
-
Channel負責管理和建立連接
-
Handler是責任鏈路模式中的處理者
-
Util是Netty提供和使用到的一些工具
如何啟動Netty服務器
Netty的啟動服務器相關的類全部都在bootstrap包里面。所以本章我們從頭開始,從bootstrap包里面的內容開始。從創建一個Netty服務器開始為大家逐步講解Netty的應用。
相比於第五章的ChannelHandler里面的編解碼器bootstrap里面可以說是內容少的可憐。來看一下他的包內容:
簡簡單單的三個類,一個接口。
Bootstrap是客戶端的啟動程序類。
ServerBootstrap是服務端的啟動程序類
Bootstrap和ServerBootstrap繼承AbstractBootstrap。
ChannelFactory則是AbstractBootstrap中用於創建Channel的接口
以下代碼以服務端的啟動程序啟動為例:
步驟一:實例化ServerBootstrap
首先我們需要實例化一個ServerBootstrap服務端啟動引導程序。如下圖:
步驟二:設置它的線程組
創建兩個NioEventLoopGroup,一個是父線程(Boss線程),一個是子線程(work線程)。
設置bootstrap的線程組
設置線程組主要的目的是為了處理Channel中的事件和IO操作。
下圖為ServerBootstrap的group方法的源碼:
父線程組被傳遞到父類中。詳細的解釋在最后面。涉及的東西太多。在后面在進行解釋。
步驟三:設置Channel類型
設置Channel類型:
下圖ServerBootstrap中channel()方法的源碼:
我們可以看到創建並設置了一個Channel工廠。
下圖是BootstrapChannelFactory的源碼。它是一個終態的靜態的類。實現ChannelFactory。作用是根據初始設置的Channel類型,創建並返回一個新的Channel。
步驟四:設置責任鏈路
責任鏈模式是Netty的核心部分。每個處理者只負責自己有關的東西。然后將處理結果根據責任鏈傳遞下去。
我們要在初始的設置一個責任鏈路。當一個Channel被創建之后初始化的時候將被設置。下圖是ServerBootstrap在init()方法的源碼:
創建一個Channel,在初始化的設置管道里面的處理者。
步驟五:綁定並監聽端口
綁定並設置監聽端口。
經過以上的5個步驟,我們的服務器就足以啟動了。很多的設置都是Netty默認的。我們想設置自己的參數怎么辦呢?Netty提供了這個方法。
步驟六:其他設置
1. 設置Channel選項配置:
在Netty 以前的版本中都是以字符串來配置的。4.x版本發布之后統一修改為使用ChannelOption類來實現配置。
例如:
Socket連接是否保存連接:
還有很多其他的參數。如下圖所示:
這里不詳細講了。參考:io.netty.channel.ChannelOption
2. 設置子Channel的屬性:
設置子Channel的屬性。當值為null是,屬性將被刪除。
解釋EventLoopGroup
這里解釋一下我們上面創建的兩個完全一樣的線程組的作用。
Netty的架構使用了非常復雜的主從式Reactor線程模型。簡單的說就是。父線程組(代碼中的parentBosser)擔任(acceptor)的角色。負責接收客戶端的連接請求,處理完成請求,創建一個Channel並注冊到子線程組(代碼中的childWorker)中的某個線程上面,然后這個線程將負責Channel的讀寫,編解碼等操作。
源代碼查看:
在步驟四中我們設置了責任鏈路。這里是Channel初始化和注冊。在這里的init就是Channel的初始化。初始化完成之后。Group()則是獲取在步驟一種的設置父線程組,並將這個新的Channel注冊進來。
下圖是AbstractBootstrap的initAndRegister方法
方法Init()實現在ServerBootstrap中。代碼如下:
看到下面的代碼是不是有種和熟悉的感覺?沒錯。就是在步驟四中設置責任鏈路的那段代碼。這里將注冊新創建的Channel到子線程組
Ps: 完。。。O(∩_∩)O哈哈~。。。寫的好辛苦的說。。。附上我的測試示例代碼。好累。。寫這么多字。希望能幫助到大家

1 import io.netty.bootstrap.ServerBootstrap; 2 import io.netty.channel.*; 3 import io.netty.channel.nio.NioEventLoopGroup; 4 import io.netty.channel.socket.nio.NioServerSocketChannel; 5 import io.netty.channel.socket.nio.NioSocketChannel; 6 import io.netty.handler.codec.LengthFieldBasedFrameDecoder; 7 import io.netty.handler.codec.LengthFieldPrepender; 8 9 /** 10 * 測試。。O(∩_∩)O哈哈~ 11 * Created by TinyZ on 2014/8/12. 12 */ 13 public class MainTest { 14 15 public static void main(String[] args) throws Exception { 16 17 NioEventLoopGroup parentBosser = new NioEventLoopGroup(); 18 NioEventLoopGroup childWorker = new NioEventLoopGroup(); 19 20 ServerBootstrap bootstrap = new ServerBootstrap(); 21 bootstrap.group(parentBosser, childWorker); 22 bootstrap.channel(NioServerSocketChannel.class); 23 bootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() { 24 @Override 25 protected void initChannel(NioSocketChannel ch) throws Exception { 26 ChannelPipeline cp = ch.pipeline(); 27 // 基於長度的解碼器 28 cp.addLast("framer", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 2, 0, 2)); 29 cp.addLast("prepender", new LengthFieldPrepender(4)); 30 // 31 cp.addLast("handler", new SimpleChannelInboundHandler<Object>() { 32 33 @Override 34 protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { 35 36 System.out.println(); 37 ctx.channel().writeAndFlush(msg); 38 39 } 40 }); 41 } 42 }); 43 bootstrap.option(ChannelOption.SO_KEEPALIVE, true); 44 //bootstrap.childAttr() 45 try { 46 // 綁定並監聽端口 47 ChannelFuture future = bootstrap.bind(9002).sync(); 48 // 等待關閉事件 49 future.channel().closeFuture().sync(); 50 } finally { 51 // 釋放資源 52 parentBosser.shutdownGracefully(); 53 childWorker.shutdownGracefully(); 54 } 55 } 56 }
作者:TinyZ
出處:http://www.cnblogs.com/zou90512/
關於作者:努力學習,天天向上。不斷探索學習,提升自身價值。記錄經驗分享。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接
如有問題,可以通過 zou90512@126.com 聯系我,非常感謝。
筆者網店: http://aoleitaisen.taobao.com. 歡迎廣大讀者圍觀