Descrição
A partir da versão 4.x, o Workerman aprimorou o suporte ao serviço HTTP. Foram introduzidas classes de requisição, resposta, session e SSE. Se você deseja usar o serviço HTTP do Workerman, é fortemente recomendado que utilize a versão 4.x ou uma versão superior.
Observe que as práticas a seguir são para a 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 oferece mecanismos de armazenamento de sessão em arquivo e em redis. Por padrão, utiliza o mecanismo de armazenamento em arquivo. Se você deseja alterar para o mecanismo de armazenamento em redis, 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 subjacente
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 mecanismo de armazenamento padrão, os dados da sessão são armazenados no disco, e o local padrão é o retornado por session_save_path(). Você pode usar o método a seguir para alterar o local de armazenamento.
use Workerman\Worker;
use \Workerman\Protocols\Http\Session\FileSessionHandler;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
// Definir o local de armazenamento dos arquivos de 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 usar o mecanismo padrão de armazenamento de sessão, haverá múltiplos arquivos de sessão no disco. O Workerman irá limpar os arquivos de sessão expirados com base nas configurações session.gc_probability, session.gc_divisor e session.gc_maxlifetime definidas no php.ini. Para mais informações sobre essas opções, consulte o manual do PHP.
Alterar o driver de armazenamento
Além dos mecanismos de armazenamento de sessão em arquivo e redis, o Workerman permite a adição de novos mecanismos de armazenamento de sessão por meio da interface padrão SessionHandlerInterface, como mecanismos de armazenamento de sessão em MongoDB, MySQL, entre outros.
Processo de adição de novos mecanismos de armazenamento de sessão
- Implemente a interface SessionHandlerInterface.
- Utilize o método
Workerman\Protocols\Http\Session::handlerClass($class_name, $config)para substituir a interface SessionHandler subjacente.
Implementando a interface SessionHandlerInterface
Um driver de armazenamento de sessão personalizado deve implementar a interface SessionHandlerInterface. Esta interface contém os seguintes métodos:
SessionHandlerInterface {
/* Métodos */
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
}
Descrição da SessionHandlerInterface
- O método read é usado para ler todos os dados da sessão correspondentes ao session_id do armazenamento. Não faça operações de desserialização, a estrutura do framework já se encarrega disso automaticamente.
- O método write é usado para gravar os dados da sessão correspondentes ao session_id no armazenamento. Não faça operações de serialização, o framework também já se encarrega disso automaticamente.
- O método destroy é usado para destruir os dados da sessão correspondentes ao session_id.
- O método gc é usado para remover os dados da sessão expirados, o armazenamento deve executar a operação de exclusão em todas as sessões cuja última data de modificação seja superior a maxlifetime.
- O método close não requer nenhuma operação, basta retornar true.
- O método open não requer nenhuma operação, basta retornar true da interface.
Substituição do driver subjacente
Após implementar a 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 houver namespace, deve ser incluído o namespace completo.
- $config são os parâmetros do construtor da classe SessionHandler.
Implementação específica
Nota: esta classe MySessionHandler é apenas para ilustrar o processo de alteração do driver subjacente da sessão, MySessionHandler não pode ser usada 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]);
}
}
}
}
// Suponha que a nova classe SessionHandler implementada precise de algumas configurações
$config = ['host' => 'localhost'];
// Utilize Workerman\Protocols\Http\Session::handlerClass($class_name, $config) para alterar a classe do driver de sessão subjacente
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();