天天看點

netty系列之:netty對http2消息的封裝

​​簡介​​

​​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的一個大體的結構:

netty系列之:netty對http2消息的封裝

在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消息的封裝了。​

繼續閱讀