說明
workerman從4.x版本開始加強了HTTP服務的支持。引入了請求類、響應類、session類以及SSE。如果你想使用workerman的HTTP服務,強烈推薦使用workerman4.x或者以后的更高版本。
注意以下都是workerman4.x版本的用法,不兼容workerman3.x。
更改session存儲引擎
workerman為session提供了文件存儲引擎和redis存儲引擎。默認使用文件存儲引擎。如果想更改為redis存儲引擎,請參考如下代碼。
<?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', // 必選參數
'port' => 6379, // 必選參數
'timeout' => 2, // 可選參數
'auth' => '******', // 可選參數
'database' => 1, // 可選參數
'prefix' => 'session_' // 可選參數
];
// 使用 Workerman\Protocols\Http\Session::handlerClass方法來更改session底層驅動類
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();
設置session存儲位置
使用默認存儲引擎時session數據默認存儲在磁盤中,默認位置為session_save_path()
的返回的位置。
你可以使用以下方法改變存儲位置。
use Workerman\Worker;
use \Workerman\Protocols\Http\Session\FileSessionHandler;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
// 設置session文件存儲位置
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'));
};
// 運行worker
Worker::runAll();
session文件清理
使用默認session存儲引擎時磁盤上會有多個session文件,
workerman 會根據php.ini中設置的session.gc_probability
session.gc_divisor
session.gc_maxlifetime
選項清理過期的session文件。關于這三個選項說明參見 php手冊
更改存儲驅動
除了文件session存儲引擎和redis session存儲引擎,workerman允許你通過標準的SessionHandlerInterface 接口添加新的session存儲引擎,比如mangoDb session存儲引擎、MySQL session存儲引擎等。
添加新的session存儲引擎流程
- 實現 SessionHandlerInterface 接口
- 使用
Workerman\Protocols\Http\Session::handlerClass($class_name, $config)
方法替換底層SessionHandler接口
實現 SessionHandlerInterface 接口
自定義session存儲驅動須實現 SessionHandlerInterface 接口。這個接口包含以下方法:
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 說明
- read方法用來從存儲中讀取session_id對應的所有session數據。請不要對數據進行反序列化操作,框架會自動完成。
- write方法用來向存儲寫入session_id對應的session數據。請不要對數據進行序列化操作,框架已經自動完成。
- destroy方法用來銷毀session_id對應的session數據。
- gc方法用來刪除過期的session數據,存儲應該對最后修改時間大于maxlifetime的所有session執(zhí)行刪除操作
- close 無需任何操作,直接返回true即可
- open 無需任何操作,直接返回true接口
替換底層驅動
實現完SessionHandlerInterface接口后,使用以下方法更改session底層驅動。
Workerman\Protocols\Http\Session::handlerClass($class_name, $config);
- $class_name 為實現SessionHandlerInterface接口的SessionHandler類的名字。如果有命名空間則需要帶上完整的命名空間
- $config 為SessionHandler類的構造函數的參數
具體實現
注意,這個MySessionHandler類僅僅為了說明更改session底層驅動的流程,MySessionHandler并不能用于生產環(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]);
}
}
}
}
// ?假設新實現的SessionHandler類需要一些配置傳入
$config = ['host' => 'localhost'];
// 使用 Workerman\Protocols\Http\Session::handlerClass($class_name, $config) 來更改session底層驅動類
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();