簡介
http2消息的結構
netty對http2的封裝
http2stream
http2frame
總結
簡介
無論是什麼協定,如果要真正被使用的話,需要将該協定轉換成為對應的語言才好真正的進行應用,本文将從http2消息的結構出發,探讨一下netty對http2消息的封裝,帶大家領略一下真正的架構應該做到什麼程度。
http2消息的結構
http2和http1.1不同的是它使用了新的二進制分幀,通過用戶端和伺服器端建立資料流steam來進行用戶端和伺服器端之間消息的互動。其中資料流是一個雙向位元組流,用來發送一條或者多條消息。
消息是用戶端和服務端發送的一個邏輯上完整的資料。根據資料大小的不同,可以将消息劃分為不同的幀frame。也就是說message是由不同的frame組成的。
frame就是http2中進行通信的最小機關,根據上一節的介紹,我們知道frame有這樣幾種:
data frame
headers frame
priority frame
rst_stream frame
settings acknowledgment frame
settings frame
ping frame
ping acknowledgment
push_promise frame
go_away frame
window_update frame
unknown frame
我們看一下http2中stream和frame的一個大體的結構:
在http2中,一個tcp連接配接,可以承載多個資料流stream,多個stream中的不同frame可以交錯發送。
每個frame通過stream id來标記其所屬的stream。
有了上面的http2的基本概念,我們接下來就看下netty對http2的封裝了。
netty對http2的封裝
作為一個tcp連接配接下面的最大的機關stream,netty中提供了接口http2stream。注意,http2stream是一個接口,它有兩個實作類,分别是defaultstream和connectionstream。
http2stream中有兩個非常重要的屬性,分别是id和state。
id前面已經介紹了,是stream的唯一标記。這裡要注意由用戶端建立的 stream id 必須是奇數,而由服務端建立的 stream id 必須是偶數。另外stream id 為 0 的流有特殊的作用,它是connection_stream_id,1 表示http_upgrade_stream_id。
state表示stream的狀态,具體而言,stream有下面幾個狀态:
為什麼狀态需要區分local和remote呢?這是因為stream連接配接的兩端,是以有兩端的狀态。
和stream狀态相對應的就是http2的生命周期了。netty提供了http2lifecyclemanager來表示對http2生命周期的管理:
分别是關閉stream,重置stream,拒絕建立stream:goaway,和處理出錯狀态這幾種。
stream之後,就是真實承載http2消息的http2frame了。在netty中,http2frame是一個接口,它有很多具體的實作。
http2frame的直接子類包括http2goawayframe、httppingframe、http2settingsframe和http2settingsackframe。
其中goaway表示不接受新的stream,ping用來進行心跳檢測。settings用來修改連接配接或者 stream 流的配置。
netty中專門有一個http2settings類和其對應。
在這個類中定義了一些特别的setting名字:
<col>
settings 名字
含義
settings_header_table_size
對端索引表的最大尺寸
settings_enable_push
是否啟用伺服器推送功能
settings_max_concurrent_streams
接收端允許的最大并發 stream 數量
settings_initial_window_size
發送端的視窗大小,用于 stream 級别流控
settings_max_frame_size
設定幀的最大大小
settings_max_header_list_size
對端頭部索引表的最大尺寸
除了上面講的4個frame之外,其他的frame實作都繼承自http2streamframe,具體而言有priorityframe,resetframe,headersframe,dataframe,windowupdateframe,pushpromiseframe和unknownframe。
各個frame分别代表了不同的功能。這裡最重要的就是http2headersframe和http2dataframe。
http2headersframe主要是用戶端發送給伺服器端的http2請求。
具體而言除了标準的http1.1的header之外,http2還支援下面的header:
對于http2dataframe來說,他本身是一個bytebufholder,用來傳遞具體的資料資訊。data frame的payload直接存儲在bytebuf中。
總結
以上就是netty對http2消息的封裝了。