Description
Workerman has enhanced support for HTTP services since version 4.x. It introduces request classes, response classes, session classes, and SSE. If you want to use Workerman's HTTP services, it is strongly recommended to use Workerman 4.x or later versions.
Note that the following are usages for Workerman 4.x and are not compatible with Workerman 3.x.
Change the Session Storage Engine
Workerman provides file storage engine and redis storage engine for sessions. The default is to use the file storage engine. If you want to change to the redis storage engine, please refer to the following code.
<?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 configuration
$config = [
'host' => '127.0.0.1', // required parameter
'port' => 6379, // required parameter
'timeout' => 2, // optional parameter
'auth' => '******', // optional parameter
'database' => 1, // optional parameter
'prefix' => 'session_' // optional parameter
];
// Use Workerman\Protocols\Http\Session::handlerClass method to change the underlying session handler class
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();
Set Session Storage Location
When using the default storage engine, session data is stored on disk, with the default location being the return value of session_save_path().
You can use the following method to change the storage location.
use Workerman\Worker;
use \Workerman\Protocols\Http\Session\FileSessionHandler;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
// Set session file storage location
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'));
};
// Run worker
Worker::runAll();
Session File Cleanup
When using the default session storage engine, there will be multiple session files on the disk.
Workerman will clean up expired session files based on the session.gc_probability, session.gc_divisor, and session.gc_maxlifetime options set in php.ini. For explanations of these three options, refer to the PHP manual.
Change Storage Driver
In addition to the file session storage engine and redis session storage engine, Workerman allows you to add new session storage engines through the standard SessionHandlerInterface interface, such as mongoDB session storage engine, MySQL session storage engine, etc.
Steps to add a new session storage engine
- Implement the SessionHandlerInterface interface
- Use
Workerman\Protocols\Http\Session::handlerClass($class_name, $config)method to replace the underlying SessionHandler interface
Implementing SessionHandlerInterface Interface
Custom session storage drivers must implement the SessionHandlerInterface interface. This interface contains the following methods:
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
}
Explanation of SessionHandlerInterface
- The
readmethod is used to read all session data corresponding to the session_id from storage. Please do not perform deserialization operations on the data; the framework will do this automatically. - The
writemethod is used to write session data corresponding to the session_id into storage. Please do not perform serialization operations on the data; the framework has already done this automatically. - The
destroymethod is used to destroy session data corresponding to the session_id. - The
gcmethod is used to delete expired session data; storage should delete all sessions with a last modified time greater than maxlifetime. - The
closemethod requires no operations; simply return true. - The
openmethod requires no operations; simply return true.
Replacing the Underlying Driver
After implementing the SessionHandlerInterface, use the following method to change the underlying session driver.
Workerman\Protocols\Http\Session::handlerClass($class_name, $config);
$class_nameis the name of the SessionHandler class that implements the SessionHandlerInterface. If there is a namespace, it must include the full namespace.$configis the parameters for the constructor of the SessionHandler class.
Specific Implementation
Note that this MySessionHandler class is only for illustrating the process of changing the underlying session driver, and MySessionHandler cannot be used in production environments.
<?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]);
}
}
}
}
// Suppose the newly implemented SessionHandler class needs some configuration passed in
$config = ['host' => 'localhost'];
// Use Workerman\Protocols\Http\Session::handlerClass($class_name, $config) to change the underlying session driver class
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();