超全局數(shù)組$_SESSION
$_SESSION
是什么
GatewayWorker中的超全局數(shù)組$_SESSION
和PHP自身的$_SESSION
功能基本相同。每個client_id對應一個$_SESSION
數(shù)組,$_SESSION
數(shù)組中可以保存對應客戶端的會話數(shù)據(jù),對應的client_id的后續(xù)請求可以直接使用這個數(shù)組中的數(shù)據(jù),而不用去反復讀取存儲。
$_SESSION
使用場景
例如客戶端鏈接GatewayWorker后,需要發(fā)送驗證數(shù)據(jù)讓服務端驗證是否合法,一般要傳遞一次用戶名和密碼數(shù)據(jù),然后在Gateway::onMessage($client_id, $message)
中通過查詢數(shù)據(jù)庫驗證$message
中的用戶名密碼是否正確,如果正確就可以將用戶的uid寫入到$_SESSION
中如$_SESSION['uid']=$uid;
,那么當這個client_id再次發(fā)來數(shù)據(jù)時,要判斷這個客戶端是否是被驗證過的,就可以用$_SESSION['uid']
是否被設置來判斷。
$_SESSION
使用注意事項
- 使用
$_SESSION
時無需調(diào)用session_start等函數(shù),可直接使用 $_SESSION
中無法保存資源類型的數(shù)據(jù)$_SESSION
數(shù)據(jù)保存在Gateway進程內(nèi)存中,無磁盤IO,性能非常好$_SESSION
的生命周期與client_id對應socket連接的生命周期相同,當客戶端連接斷開后,對應的客戶端$_SESSION
將會清除- GatewayWorker中的
$_SESSION
與WebServer(PHP-FPM/Apache等)中的$_SESSION
無法互通 - 定時器中不要直接使用
$_SESSION
變量,因為定時器運行那一刻無法確定$_SESSION
變量里存儲的值屬于哪個client_id。如果定時器里面需要獲得session,可以使用Gateway::getSession($client_id)
獲取
$_SESSION
實現(xiàn)原理
Gateway/Worker中,每個客戶端的$_SESSION
數(shù)據(jù)是存儲在Gateway進程內(nèi)存中的,每次Gateway進程轉發(fā)消息給BusinessWorker進程時,都會順便攜帶上對應客戶端的$_SESSION
數(shù)據(jù)給BusinessWorker進程,這時BusinessWorker進程就能使用$_SESSION
了。而當$_SESSION
數(shù)據(jù)有更改時,BusinessWorker會將新的$_SESSION
數(shù)據(jù)傳遞給Gateway進程進行保存。
示例
class Events
{
public static function onMessage($client_id, $data)
{
// data={"type":"login", "uid":"666"}
$data = json_decode($data, true);
// 如果沒有$_SESSION['uid']說明客戶端沒有登錄
if(!isset($_SESSION['uid']))
{
// 消息類型不是登錄視為非法請求,關閉連接
if($data['type'] !== 'login')
{
return Gateway::closeClient($client_id);
}
// 設置session,標記該客戶端已經(jīng)登錄
$_SESSION['uid'] = $data['uid'];
}
}
}