Объяснение
С 4.x версии workerman значительно усилил поддержку HTTP-сервиса. Был введен класс запроса, класс ответа, класс сеанса и SSE. Если вы хотите использовать HTTP-сервис workerman, настоятельно рекомендуется использовать версию workerman 4.x или более позднюю.
Обратите внимание, что все нижеперечисленное относится к использованию версии workerman 4.x и несовместимо с версией workerman 3.x.
Изменение механизма хранения сеансов
Workerman предоставляет движки хранения сеансов на основе файлов и 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::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_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';
// Установить место хранения файлов сеанса
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();
Очистка файлов сеансов
При использовании двигателя хранения сеансов по умолчанию на диске создается несколько файлов сеансов. Workerman будет очищать устаревшие файлы сеансов в соответствии с параметрами session.gc_probability
, session.gc_divisor
и session.gc_maxlifetime
, установленными в php.ini. См. документацию по php для более подробной информации об этих параметрах.
Изменение хранилища
Помимо файлового и Redis-движков хранения сеансов, workerman позволяет добавлять новые движки хранения сеансов, используя стандартный интерфейс SessionHandlerInterface, такие как движок хранения сеансов на основе mangoDB или MySQL.
Процесс добавления нового двигателя хранения сеансов
- Реализуйте интерфейс SessionHandlerInterface
- Используйте метод
Workerman\Protocols\Http\Session::handlerClass($class_name, $config)
для замены базового класса SessionHandlerInterface.
Реализация интерфейса SessionHandlerInterface
Пользовательский двигатель хранения сеансов должен реализовывать интерфейс SessionHandlerInterface. Этот интерфейс включает следующие методы:
SessionHandlerInterface {
/* Методы */
public function read ( string $session_id ) : string
public function write ( string $session_id , string $session_data ) : bool
public function destroy ( string $session_id ) : bool
public function gc ( int $maxlifetime ) : int
public function close ( void ) : bool
public function open ( string $save_path , string $session_name ) : bool
}
Объяснение интерфейса SessionHandlerInterface
- Метод read используется для чтения всех данных сеанса, соответствующих идентификатору сеанса, из хранилища. Не выполняйте десериализацию данных, это будет сделано автоматически фреймворком.
- Метод write используется для записи данных сеанса, соответствующих идентификатору сеанса, в хранилище. Не выполняйте сериализацию данных, это уже сделано автоматически фреймворком.
- Метод destroy используется для удаления данных сеанса, соответствующих идентификатору сеанса.
- Метод gc используется для удаления устаревших данных сеанса. Хранилище должно удалять все сеансы, которые не были изменены за время, превышающее maxlifetime.
- Метод close не требует выполнения каких-либо действий, просто возвращает true.
- Метод open не требует выполнения каких-либо действий, просто возвращает true.
Замена базового двигателя
После реализации интерфейса SessionHandlerInterface используйте следующий метод для замены базового двигателя сеансов.
Workerman\Protocols\Http\Session::handlerClass($class_name, $config);
- $class_name - имя класса, реализующего интерфейс SessionHandlerInterface. Если класс находится в пространстве имен, укажите полное пространство имен.
- $config - параметры конструктора класса SessionHandler.
Конкретная реализация
Обратите внимание, что класс MySessionHandler приведен лишь для пояснения процесса замены базового двигателя сеансов, и использовать его в производственной среде не рекомендуется.
<?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::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();