說(shuō)明
workerman從4.x版本開始加強(qiáng)了HTTP服務(wù)的支持。引入了請(qǐng)求類、響應(yīng)類、session類以及SSE。如果你想使用workerman的HTTP服務(wù),強(qiáng)烈推薦使用workerman4.x或者以后的更高版本。
注意以下都是workerman4.x版本的用法,不兼容workerman3.x。
更改session存儲(chǔ)引擎
workerman為session提供了文件存儲(chǔ)引擎和redis存儲(chǔ)引擎。默認(rèn)使用文件存儲(chǔ)引擎。如果想更改為redis存儲(chǔ)引擎,請(qǐng)參考如下代碼。
<?php
use Workerman\Worker;
use Workerman\Protocols\Http\Session;
use Workerman\Protocols\Http\Session\RedisSessionHandler;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
//?redis配置
$config = [
'host' => '127.0.0.1', // 必選參數(shù)
'port' => 6379, // 必選參數(shù)
'timeout' => 2, // 可選參數(shù)
'auth' => '******', // 可選參數(shù)
'database' => 1, // 可選參數(shù)
'prefix' => 'session_' // 可選參數(shù)
];
// 使用 Workerman\Protocols\Http\Session::handlerClass方法來(lái)更改session底層驅(qū)動(dòng)類
Session::handlerClass(RedisSessionHandler::class, $config);
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$session = $request->session();
$session->set('somekey', rand());
$connection->send($session->get('somekey'));
};
Worker::runAll();
設(shè)置session存儲(chǔ)位置
使用默認(rèn)存儲(chǔ)引擎時(shí)session數(shù)據(jù)默認(rèn)存儲(chǔ)在磁盤中,默認(rèn)位置為session_save_path()
的返回的位置。
你可以使用以下方法改變存儲(chǔ)位置。
use Workerman\Worker;
use \Workerman\Protocols\Http\Session\FileSessionHandler;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
// 設(shè)置session文件存儲(chǔ)位置
FileSessionHandler::sessionSavePath('/tmp/session');
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$session = $request->session();
$session->set('name', 'tome');
$connection->send($session->get('name'));
};
// 運(yùn)行worker
Worker::runAll();
session文件清理
使用默認(rèn)session存儲(chǔ)引擎時(shí)磁盤上會(huì)有多個(gè)session文件,
workerman 會(huì)根據(jù)php.ini中設(shè)置的session.gc_probability
session.gc_divisor
session.gc_maxlifetime
選項(xiàng)清理過(guò)期的session文件。關(guān)于這三個(gè)選項(xiàng)說(shuō)明參見 php手冊(cè)
更改存儲(chǔ)驅(qū)動(dòng)
除了文件session存儲(chǔ)引擎和redis session存儲(chǔ)引擎,workerman允許你通過(guò)標(biāo)準(zhǔn)的SessionHandlerInterface 接口添加新的session存儲(chǔ)引擎,比如mangoDb session存儲(chǔ)引擎、MySQL session存儲(chǔ)引擎等。
添加新的session存儲(chǔ)引擎流程
- 實(shí)現(xiàn) SessionHandlerInterface 接口
- 使用
Workerman\Protocols\Http\Session::handlerClass($class_name, $config)
方法替換底層SessionHandler接口
實(shí)現(xiàn) SessionHandlerInterface 接口
自定義session存儲(chǔ)驅(qū)動(dòng)須實(shí)現(xiàn) SessionHandlerInterface 接口。這個(gè)接口包含以下方法:
SessionHandlerInterface {
/* Methods */
abstract public read ( string $session_id ) : string
abstract public write ( string $session_id , string $session_data ) : bool
abstract public destroy ( string $session_id ) : bool
abstract public gc ( int $maxlifetime ) : int
abstract public close ( void ) : bool
abstract public open ( string $save_path , string $session_name ) : bool
}
SessionHandlerInterface 說(shuō)明
- read方法用來(lái)從存儲(chǔ)中讀取session_id對(duì)應(yīng)的所有session數(shù)據(jù)。請(qǐng)不要對(duì)數(shù)據(jù)進(jìn)行反序列化操作,框架會(huì)自動(dòng)完成。
- write方法用來(lái)向存儲(chǔ)寫入session_id對(duì)應(yīng)的session數(shù)據(jù)。請(qǐng)不要對(duì)數(shù)據(jù)進(jìn)行序列化操作,框架已經(jīng)自動(dòng)完成。
- destroy方法用來(lái)銷毀session_id對(duì)應(yīng)的session數(shù)據(jù)。
- gc方法用來(lái)刪除過(guò)期的session數(shù)據(jù),存儲(chǔ)應(yīng)該對(duì)最后修改時(shí)間大于maxlifetime的所有session執(zhí)行刪除操作
- close 無(wú)需任何操作,直接返回true即可
- open 無(wú)需任何操作,直接返回true接口
替換底層驅(qū)動(dòng)
實(shí)現(xiàn)完SessionHandlerInterface接口后,使用以下方法更改session底層驅(qū)動(dòng)。
Workerman\Protocols\Http\Session::handlerClass($class_name, $config);
- $class_name 為實(shí)現(xiàn)SessionHandlerInterface接口的SessionHandler類的名字。如果有命名空間則需要帶上完整的命名空間
- $config 為SessionHandler類的構(gòu)造函數(shù)的參數(shù)
具體實(shí)現(xiàn)
注意,這個(gè)MySessionHandler類僅僅為了說(shuō)明更改session底層驅(qū)動(dòng)的流程,MySessionHandler并不能用于生產(chǎn)環(huán)境。
<?php
use Workerman\Worker;
use Workerman\Protocols\Http\Session;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
class MySessionHandler implements SessionHandlerInterface
{
protected static $store = [];
public function __construct($config) {
// ['host' => 'localhost']
var_dump($config);
}
public function open($save_path, $name)
{
return true;
}
public function read($session_id)
{
return isset(static::$store[$session_id]) ? static::$store[$session_id]['content'] : '';
}
public function write($session_id, $session_data)
{
static::$store[$session_id] = ['content' => $session_data, 'timestamp' => time()];
}
public function close()
{
return true;
}
public function destroy($session_id)
{
unset(static::$store[$session_id]);
return true;
}
public function gc($maxlifetime) {
$time_now = time();
foreach (static::$store as $session_id => $info) {
if ($time_now - $info['timestamp'] > $maxlifetime) {
unset(static::$store[$session_id]);
}
}
}
}
// ?假設(shè)新實(shí)現(xiàn)的SessionHandler類需要一些配置傳入
$config = ['host' => 'localhost'];
// 使用 Workerman\Protocols\Http\Session::handlerClass($class_name, $config) 來(lái)更改session底層驅(qū)動(dòng)類
Session::handlerClass(MySessionHandler::class, $config);
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$session = $request->session();
$session->set('somekey', rand());
$connection->send($session->get('somekey'));
};
Worker::runAll();