1、Http類設計
workerman作者在設計Http類時,還引入了另外一個類HttpCache,用於輔助設置Http的報頭、狀態碼、會話等操作。HttpCache類是在載入Http類所在的類文件時,進行調用。調用方法為: HttpCache::init()
注意,此方法僅在首次載入Http類文件時,進行調用。
2、HttpCache輔助類
2.1、類概要
2.2、核心方法解析
init()方法的作用是把php.ini配置文件中關於session的配置參數值,賦值給HttpCache類的靜態屬性如:
session名稱、session文件保存路徑、sessiongc設置、session最大生存時間
3、Http類
在實現上,並不implements協議接口,只是按照其接口規範進行實現
3.1、類概要設計
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文件名,和獲取裡面的內容
閱讀更多 iamasb 的文章