Explicação
A partir da versão 4.x, o Workerman reforçou o suporte para serviços HTTP. Introduziu classes de requisição, de resposta, de sessão e também o SSE. Se você quiser usar o serviço HTTP do Workerman, é altamente recomendável usar a versão 4.x ou superior.
Importante: Todas as orientações a seguir referem-se ao uso da versão 4.x do Workerman e não são compatíveis com a versão 3.x.
Alterar o mecanismo de armazenamento da sessão
O Workerman disponibiliza o mecanismo de armazenamento de sessão em arquivo e em Redis. O padrão é o armazenamento em arquivo. Se desejar alterar para o armazenamento em Redis, por favor, consulte o código abaixo.
<?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');
// Configuração do Redis
$config = [
'host' => '127.0.0.1', // parâmetro obrigatório
'port' => 6379, // parâmetro obrigatório
'timeout' => 2, // parâmetro opcional
'auth' => '******', // parâmetro opcional
'database' => 1, // parâmetro opcional
'prefix' => 'session_' // parâmetro opcional
];
// Use o método Workerman\Protocols\Http\Session::handlerClass para alterar a classe do driver de sessão
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();
Definir o local de armazenamento da sessão
Ao utilizar o armazenamento padrão, os dados da sessão são armazenados por padrão no disco, na localização retornada por session_save_path()
. Você pode alterar o local de armazenamento com o seguinte método.
use Workerman\Worker;
use \Workerman\Protocols\Http\Session\FileSessionHandler;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
// Configuração do local de armazenamento do arquivo da sessão
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'));
};
// Executar o worker
Worker::runAll();
Limpeza de arquivos de sessão
Ao utilizar o mecanismo de armazenamento padrão da sessão, vários arquivos de sessão podem ser armazenados no disco. O Workerman irá limpar os arquivos de sessão expirados de acordo com as configurações session.gc_probability
, session.gc_divisor
e session.gc_maxlifetime
presentes no php.ini. Para mais informações sobre essas três configurações, consulte o manual do PHP.
Alterar o driver de armazenamento
Além dos mecanismos de armazenamento de sessão em arquivo e em Redis, o Workerman permite adicionar novos mecanismos de armazenamento de sessão, como o mecanismo de armazenamento de sessão em MongoDB e em MySQL, através da interface padrão SessionHandlerInterface.
Processo para adicionar um novo mecanismo de armazenamento de sessão
- Implementar a interface SessionHandlerInterface.
- Utilizar o método
Workerman\Protocols\Http\Session::handlerClass($class_name, $config)
para substituir a interface subjacente do SessionHandler.
Implementar a interface SessionHandlerInterface
O mecanismo de armazenamento personalizado da sessão deve implementar a interface SessionHandlerInterface, que inclui os seguintes métodos:
SessionHandlerInterface {
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
}
Explicação da interface SessionHandlerInterface
- O método read é usado para ler todos os dados da sessão correspondentes ao session_id do armazenamento. Não é necessário deserializar os dados, o framework fará isso automaticamente.
- O método write é usado para escrever os dados da sessão correspondentes ao session_id no armazenamento. Não é necessário serializar os dados, o framework já o faz automaticamente.
- O método destroy é usado para destruir os dados da sessão correspondentes ao session_id.
- O método gc é usado para excluir os dados da sessão expirados, o armazenamento deve executar a exclusão de todas as sessões com horário de última modificação superior a maxlifetime.
- O método close não requer nenhuma operação, apenas retorne true.
- O método open não requer nenhuma operação, apenas retorne true.
Substituir o driver subjacente
Após a implementação da interface SessionHandlerInterface, utilize o método a seguir para alterar o driver subjacente da sessão.
Workerman\Protocols\Http\Session::handlerClass($class_name, $config);
- $class_name é o nome da classe SessionHandler que implementa a interface SessionHandlerInterface. Se estiver em um namespace, o namespace completo deve ser incluído.
- $config são os parâmetros do construtor da classe SessionHandler.
Implementação específica
Observação: Esta classe MySessionHandler é apenas para ilustrar o processo de alteração do driver subjacente da sessão e não deve ser utilizada em um ambiente de produção.
<?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]);
}
}
}
}
// Supondo que a nova classe MySessionHandler implementada requer algum parâmetro de configuração
$config = ['host' => 'localhost'];
// Use o método Workerman\Protocols\Http\Session::handlerClass($class_name, $config) para alterar a classe do driver subjacente da sessão
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();