【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )
文章目錄
- 一、 代碼示例分析
- 二、 ChannelHandlerContext 雙向鏈表類型
- 三、 Pipeline / ChannelPipeline 管道內(nèi)雙向鏈表分析
- 四、 數(shù)據(jù)入站與出站
接上一篇博客 【Netty】Netty 核心組件 ( Pipeline | ChannelPipeline ) 內(nèi)容 , 在 debug 調(diào)試中 , 詳細(xì)分析 ChannelPipeline 內(nèi)部的 Handler 雙向鏈表 ;
一、 代碼示例分析
1 . 基于以下代碼分析 :
// 1. 之前創(chuàng)建 bossGroup workerGroup 兩個線程池 // 省略一萬行代碼 ...// 2. 服務(wù)器啟動對象, 需要為該對象配置各種參數(shù) ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) // 設(shè)置 主從 線程組 , 分別對應(yīng) 主 Reactor 和 從 Reactor.channel(NioServerSocketChannel.class) // 設(shè)置 NIO 網(wǎng)絡(luò)套接字通道類型.option(ChannelOption.SO_BACKLOG, 128) // 設(shè)置線程隊(duì)列維護(hù)的連接個數(shù).childOption(ChannelOption.SO_KEEPALIVE, true) // 設(shè)置連接狀態(tài)行為, 保持連接狀態(tài)// 核心分析代碼 ------------------------------------------------------------------------.childHandler( // 為 WorkerGroup 線程池對應(yīng)的 NioEventLoop 設(shè)置對應(yīng)的事件 處理器 Handlernew ChannelInitializer<SocketChannel>() {// 創(chuàng)建通道初始化對象@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 該方法在服務(wù)器與客戶端連接建立成功后會回調(diào)// 獲取管道ChannelPipeline pipeline = ch.pipeline();// 為管道加入 HTTP 協(xié)議的編解碼器 HttpServerCodec,// codec 中的 co 是 coder 編碼器的意思, dec 是 decoder 解碼器的意思// 第一個字符串是編解碼器的名稱pipeline.addLast("HttpServerCodec" , new HttpServerCodec());// 為管道 Pipeline 設(shè)置處理器 Hanedlerpipeline.addLast("HTTPServerHandler", new HTTPServerHandler());// 管道初始化完成// 在此行代碼上打斷點(diǎn) ----------------------------------------------System.out.println("管道初始化完成!");}});// 核心分析代碼 ------------------------------------------------------------------------2 . 元素類型 :
① 頭尾元素 : 雙向鏈表的頭尾都是自動生成的 , 其類型是 DefaultChannelPipeline , 頭尾元素中沒有封裝 Handler 處理器 ;
② 中間元素 : 雙向鏈表的中間元素是 DefaultChannelHandlerContext 類型的 , 封裝了 Handler 處理器 ;
3 . 雙向鏈表元素內(nèi)封裝的 ChannelHandler 類型 : 從頭元素之后的第一個元素開始到最后一個元素之間 , 每個雙向鏈表中的元素都封裝有一個 ChannelHandler ;
4 . ChannelPipeline 管道中 , 放入了 333 個 Handler 處理器 ;
① ChannelInitializer : 通道初始化器 ;
② HttpServerCodec : HTTP 服務(wù)器編解碼器 ;
③ HTTPServerHandler : 用戶自定義的 HTTP 服務(wù)器業(yè)務(wù)邏輯處理器 ;
5 . ChannelPipeline 管道添加 ChannelHandler 處理器 :
① addFirst : 將 ChannelHandler 處理器添加到雙向鏈表的表頭 ;
ChannelPipeline addFirst(String name, ChannelHandler handler); ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);② addLast : 將 ChannelHandler 處理器添加到雙向鏈表的尾部 ;
ChannelPipeline addLast(String name, ChannelHandler handler); ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);二、 ChannelHandlerContext 雙向鏈表類型
1 . 表頭元素和表尾元素類型 : 雙向鏈表的表頭元素和表尾元素都是 DefaultChannelPipeline 類型的 , 該類型沒有封裝 ChannelHandler 處理器 ;
2 . 雙向鏈表中間類型 : 表頭表尾中間類型是 DefaultChannelHandlerContext 類型的 , 該類型中封裝了 ChannelHandler 處理器 ;
3 . ChannelHandlerContext 類型 :
final class DefaultChannelHandlerContext extends AbstractChannelHandlerContext {private final ChannelHandler handler;DefaultChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutor executor, String name, ChannelHandler handler) {super(pipeline, executor, name, isInbound(handler), isOutbound(handler));if (handler == null) {throw new NullPointerException("handler");}this.handler = handler;}@Overridepublic ChannelHandler handler() {return handler;}private static boolean isInbound(ChannelHandler handler) {return handler instanceof ChannelInboundHandler;}private static boolean isOutbound(ChannelHandler handler) {return handler instanceof ChannelOutboundHandler;} }三、 Pipeline / ChannelPipeline 管道內(nèi)雙向鏈表分析
0 . 雙向鏈表表頭 head ( 第 000 個元素 ) : 打開 head 元素的成員 , 查看其成員組成 ;
① prev 為空 : 這是雙向鏈表的表頭 , 因此其 prev 元素 ( 前一個元素 ) 是空的 ;
② next 元素 : 查看其下一個元素 , 其下一個元素肯定也是 ChannelHandlerContext 類型的 ;
③ 開始表頭元素類型 : DefaultChannelPipeline ;
1 . 雙向鏈表第 111 個元素 Handler 類型 : 其 Handler 是 HTTPServer 中的匿名內(nèi)部類 ChannelInitializer , 也就是創(chuàng)建的 ChannelInitializer 匿名內(nèi)部類 ;
第 111 個元素 Handler 類型 : ChannelInitializer , 該類繼承了 ChannelInboundHandlerAdapter , 因此也是一個處理器 Handler ;
public abstract class ChannelInitializer<C extends Channel> extends ChannelInboundHandlerAdapter2 . 雙向鏈表第 222 個元素 Handler 類型 : 其 Handler 是 HttpServerCodec 類型的對象, 也就是為 ChannelPipeline 添加的 HttpServerCodec 編解碼器 ;
第 222 個元素 Handler 類型 : HttpServerCodec ;
// 獲取管道 ChannelPipeline pipeline = ch.pipeline();// 本次示例核心代碼 --------------------------------------------- // 為管道加入 HTTP 協(xié)議的編解碼器 HttpServerCodec, // codec 中的 co 是 coder 編碼器的意思, dec 是 decoder 解碼器的意思 // 第一個字符串是編解碼器的名稱 pipeline.addLast("HttpServerCodec" , new HttpServerCodec()); // 本次示例核心代碼 ---------------------------------------------3 . 雙向鏈表第 333 個元素 Handler 類型 : 其 Handler 是 HttpServerHandler 類型的對象, 也就是為 ChannelPipeline 添加的 HTTPServerHandler 業(yè)務(wù)邏輯處理器 ;
① 第 333 個元素 Handler 類型 : HttpServerHandler ;
② HTTPServerHandler 類結(jié)構(gòu) : 其中 HTTPServerHandler 繼承 SimpleChannelInboundHandler<HttpObject> ;
public class HTTPServerHandler extends SimpleChannelInboundHandler\<HttpObject\>③ 對應(yīng)的向管道添加 HTTPServerHandler 處理器的代碼 :
new ChannelInitializer<SocketChannel>() {// 創(chuàng)建通道初始化對象@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 該方法在服務(wù)器與客戶端連接建立成功后會回調(diào)// 獲取管道ChannelPipeline pipeline = ch.pipeline();// 為管道加入 HTTP 協(xié)議的編解碼器 HttpServerCodec,// codec 中的 co 是 coder 編碼器的意思, dec 是 decoder 解碼器的意思// 第一個字符串是編解碼器的名稱pipeline.addLast("HttpServerCodec" , new HttpServerCodec());// 本次示例核心代碼 ---------------------------------------------// 為管道 Pipeline 設(shè)置處理器 Hanedlerpipeline.addLast("HTTPServerHandler", new HTTPServerHandler());// 本次示例核心代碼 ---------------------------------------------// 管道初始化完成System.out.println("管道初始化完成!");} }4 . 雙向鏈表第 444 個元素 : 第四個元素也是雙向鏈表的結(jié)尾 , 類型是與鏈表頭元素類型一致 , 是 DefaultChannelPipeline ;
① 第 444 個元素類型 : DefaultChannelPipeline ;
② next 為空 : 其 next 為空 , 說明該元素就是雙向鏈表的結(jié)尾 ;
四、 數(shù)據(jù)入站與出站
1 . 雙向鏈表對應(yīng)的數(shù)據(jù)入站與出棧操作 :
① 鏈表中數(shù)據(jù)傳遞 : 在雙向鏈表中 , 將數(shù)據(jù)按照兩個方向進(jìn)行傳遞 , 分別是入站和出站操作 ;
② 入站數(shù)據(jù) : 從鏈表的表頭 , 傳遞數(shù)據(jù)到鏈表尾部 , 將數(shù)據(jù)逐個 Handler 傳遞 , 每個鏈表元素中的 Handler 對數(shù)據(jù)都進(jìn)行對應(yīng)的處理 ;
③ 出站數(shù)據(jù) : 從鏈表的尾部 , 向表頭傳遞數(shù)據(jù) , 經(jīng)過每個 Handler 都對數(shù)據(jù)進(jìn)行相應(yīng)的處理 ;
以上面的代碼示例為例進(jìn)行解析
2 . 示例中的入站操作 :
① 初始化雙向鏈表 : 客戶端請求服務(wù)器端資源 , 客戶端請求到來后 , 先初始化該 ChannelHandlerContext 雙向鏈表 , 分別放入 ChannelInitializer , HttpServerCodec , HTTPServerHandler 三個 ChannelHandler 通道處理器 ;
② 數(shù)據(jù)解碼 : 客戶端請求數(shù)據(jù) , 先傳入 HttpServerCodec 服務(wù)器編解碼器中進(jìn)行處理 , 這里需要將數(shù)據(jù)解碼 ;
③ 業(yè)務(wù)邏輯 : 然后將 HttpServerCodec 輸出的數(shù)據(jù) , 輸入到用戶自定義的 HTTPServerHandler 中進(jìn)行處理 ;
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Netty】Netty 核心组件 (
- 下一篇: 【Netty】Netty 核心组件 (