.NET Core 3.0之深入源码理解Kestrel的集成与应用(二)
前言
前一篇文章主要介紹了.NET Core繼承Kestrel的目的、運行方式以及相關的使用,接下來將進一步從源碼角度探討.NET Core 3.0中關于Kestrel的其他內容,該部分內容,我們無需掌握,依然可以用好Kestrel,本文只是將一些內部的技術點揭露出來,供自己及大家有一個較深的認識。
Kestrel提供了HTTP 1.X及HTTP 2.0的支持,內容比較多,從趨勢上看,Http2.0針對HTTP 1.X的眾多缺陷進行了改進,所以這篇文章主要關注Kestrel對HTTP 2.0的支持。
HTTP 2.X
流控制
在討論流控制之前,我們先看一下流控制的整體結構圖:
接下來,我們詳細討論一下流控制,其中內部有一個結構體的實現:FlowControl,FlowControl在初始化的時候設置了所能接收或者輸出的數據量大小,并會根據輸入輸出進行動態控制,畢竟資源是有限的,在有限資源的限制下,需要靈活處理數據包對資源的占用。FlowControl.Advance方法的調用會騰出空間,FlowControl.TryUpdateWindow會占用空間,以下是FlowControl的源碼:
在控制流中,主要包括FlowControl和StreamFlowControl,StreamFlowControl依賴于FlowControl(Http2Stream引用了StreamFlowControl的讀寫實現)。我們知道,在計算機網絡中,Flow和Stream都是指流的概念,Flow側重于主機或者網絡之間的雙向傳輸的數據包,Stream側重于成對的IP之間的會話。
在FlowControl的輸入輸出控制中,OutFlowControl增加了對OutputFlowControlAwaitable的引用,并采用了隊列的方式。
相關使用如下:
頭部壓縮算法
頭部壓縮算法這塊涉及到動/靜態表、哈夫曼編/解碼、整型編/解碼等。
頭部字段維護在HeaderField中,源碼如下:
靜態表由StaticTable實現,內部維護了一個只讀的HeaderField數組,動態表由DynamicTable實現,可以視為是HeaderField的一個動態數組的實現,其初始大小在實例化的時候輸入,并除以32(HeaderField.RfcOverhead)。
哈夫曼編/解碼和整型編/解碼會被HPackDecoder和HPackEncoder引用。
HPackDecoder提供了三個公共方法,這三個方法最終都會調用EncodeString進行最終的編碼,目前可以看到其內部只有整形編碼,我相信在未來會增加哈夫曼編碼,以下是EncodeString源碼(有興趣的朋友可以關注下Span<>的使用):
HPackEncoder只有一個公共方法Decode,不過其內部實現非常復雜,它實現了流的不同幀的處理、大小的控制以及多路復用。
HTTP幀處理
讀取功能主要由Http2FrameReader實現,內部有四個常數,如下所示:
HeaderLength = 9:Header長度
TypeOffset = 3:類型偏移量
FlagsOffset = 4:標記偏移量
StreamIdOffset = 5:StreamId偏移量
SettingSize = 6:Id占用2 bytes, 值占用了4 bytes
Http2PeerSettings實現,內部提供了一個Update方法用于更新配置信息。
除此以外還包括Stream生命周期處理、錯誤編碼、連接控制等,限于篇幅此處不做其他說明,有興趣的朋友可以自己查看源代碼。
總結
以上是生活随笔為你收集整理的.NET Core 3.0之深入源码理解Kestrel的集成与应用(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 再见Jenkins,从Gitlab代码提
- 下一篇: 译 | 使用Roslyn分析器高效编写更