102、Workerman通信框架-協議Http類解析

1、Http類設計

workerman作者在設計Http類時,還引入了另外一個類HttpCache,用於輔助設置Http的報頭、狀態碼、會話等操作。HttpCache類是在載入Http類所在的類文件時,進行調用。調用方法為: HttpCache::init()

注意,此方法僅在首次載入Http類文件時,進行調用。

2、HttpCache輔助類

2.1、類概要

102、Workerman通信框架-協議Http類解析

2.2、核心方法解析

init()方法的作用是把php.ini配置文件中關於session的配置參數值,賦值給HttpCache類的靜態屬性如:

session名稱、session文件保存路徑、sessiongc設置、session最大生存時間

3、Http類

在實現上,並不implements協議接口,只是按照其接口規範進行實現

3.1、類概要設計

102、Workerman通信框架-協議Http類解析

3.2、核心方法解析

  • input靜態方法

判斷是否存在 \\r\\n\\r\\n 報頭與報體分隔符,不存在則返回0,說明接收數據還不夠。但如果接收的長度大於一條鏈接的最大包長度,則認為是非法,因關閉此鏈接

存在分隔符,則進行分割,獲取報頭的信息

從報頭信息中,獲取當前的請求行中的請求方法,執行getRequestSize方法

getRequestSize方法進行如下判斷:

當請求方法為GET/OPTIONS/HEAD/DELETE這些方法時,則直接計算分割後的報頭長度+報頭與報體分隔符

當請求方法為POST,則執行正則匹配獲取Content-Length的值,然後計算Content-Length的值+分割後的報頭長度+報頭與報體分隔符

  • decode靜態方法

- 重置php中的關於http請求的全局變量如

$_POST、$_GET、$_COOKIE、$_REQUEST、$_SESSION、$_FILES、$GLOBALS['HTTP_RAW_POST_DATA']

- 實例化HttpCache()對象,並賦值給其靜態屬性$instance

- 初始化全局$_SERVER變量

- 以分隔符 \\r\\n\\r\\n分割http的報頭$http_header與報體$http_body

- 以分隔符 \\r\\n分割報頭$http_header,得到數組$header_data

- $header_data[0]為請求行,再以" " 進行分割,得到請求方法、請求url、請求協議,並依次賦值給$_SERVER全局變量

- 然後unset($header_data[0]);再遍歷$header_data,得到頭部信息鍵值對,並保存在$_SERVER全局變量

- 頭部信息CONTENT_TYPE的判斷:

-- 為multipart/form-data,這說明此請求是上傳資源

則執行parseUploadFiles($http_body, $http_post_boundary);

上傳資源的報文格式

------WebKitFormBoundary9BTgq0bt94hMtm23\\r\\nContent-Disposition: form-data; name="data"; filename="blob"\\r\\nContent-Type: application/octet-stream\\r\\n\\r\\n資源\\r\\n------WebKitFormBoundary9BTgq0bt94hMtm23\\r\\nContent-Disposition: form-data; name="index"\\r\\n\\r\\n1\\r\\n------WebKitFormBoundary9BTgq0bt94hMtm23--\\r\\n

-- application/json

$_POST = json_decode($http_body, true);

-- application/x-www-form-urlencoded

parse_str($http_body, $_POST);

  • encode靜態方法

- 按照http報文的響應格式遍歷HttpCache::$header數組

- 執行sessionWriteClose方法

判斷是否啟動session和全局變量$_SESSION是否非空

如都滿足,則$_SESSION進行序列化處理,並把序列化結果後保存在本地

  • header

設置響應報頭信息。借用輔助類HttpCache的靜態屬性$header數組,存在報頭key-value信息

4、如何啟動session

由於workerman是基於cli模式,因此,原來php的session_start已無法使用。但通過Http類的sessionStart()靜態方法,也能達到同樣的效果。

4.1、觸發

在onMessage回調方法中,進行調用Http::sessionStart()

4.2、sessionStart()執行流程

-- tryGcSessions()

根據session文件的創建時間進行判斷,如果大於session的生存時間,則進行刪除

-- 設置session啟動標誌位

-- 如果本次全局變量$_COOKIE中不存在sessionid的值和session文件不存在,則創建新的sessionid和session文件

-- 然後設置頭部信息cookie值,此操作在返回信息給客戶端時,encode方法中得到體現

-- 這樣下次,再執行sessionStart()靜態方法,就可以從cookie中獲取本地session文件名,和獲取裡面的內容


分享到:


相關文章: