说明

workerman从4.x版本开始加强了HTTP服务的支持。引入了请求类、响应类、session类以及SSE。如果你想使用workerman的HTTP服务,强烈推荐使用workerman4.x或者以后的更高版本。

注意以下都是workerman4.x版本的用法,不兼容workerman3.x。

更改session存储引擎

workerman为session提供了文件存储引擎和redis存储引擎。默认使用文件存储引擎。如果想更改为redis存储引擎,请参考如下代码。

  1. <?php
  2. use Workerman\Worker;
  3. use Workerman\Protocols\Http\Session;
  4. use Workerman\Protocols\Http\Session\RedisSessionHandler;
  5. use Workerman\Connection\TcpConnection;
  6. use Workerman\Protocols\Http\Request;
  7. require_once __DIR__ . '/vendor/autoload.php';
  8. $worker = new Worker('http://0.0.0.0:8080');
  9. // redis配置
  10. $config = [
  11. 'host' => '127.0.0.1', // 必选参数
  12. 'port' => 6379, // 必选参数
  13. 'timeout' => 2, // 可选参数
  14. 'auth' => '******', // 可选参数
  15. 'database' => 1, // 可选参数
  16. 'prefix' => 'session_' // 可选参数
  17. ];
  18. // 使用 Workerman\Protocols\Http\Session::handlerClass方法来更改session底层驱动类
  19. Session::handlerClass(RedisSessionHandler::class, $config);
  20. $worker->onMessage = function(TcpConnection $connection, Request $request)
  21. {
  22. $session = $request->session();
  23. $session->set('somekey', rand());
  24. $connection->send($session->get('somekey'));
  25. };
  26. Worker::runAll();

设置session存储位置

使用默认存储引擎时session数据默认存储在磁盘中,默认位置为session_save_path()的返回的位置。 你可以使用以下方法改变存储位置。

  1. use Workerman\Worker;
  2. use \Workerman\Protocols\Http\Session\FileSessionHandler;
  3. use Workerman\Connection\TcpConnection;
  4. use Workerman\Protocols\Http\Request;
  5. require_once __DIR__ . '/vendor/autoload.php';
  6. // 设置session文件存储位置
  7. FileSessionHandler::sessionSavePath('/tmp/session');
  8. $worker = new Worker('http://0.0.0.0:8080');
  9. $worker->onMessage = function(TcpConnection $connection, Request $request)
  10. {
  11. $session = $request->session();
  12. $session->set('name', 'tome');
  13. $connection->send($session->get('name'));
  14. };
  15. // 运行worker
  16. 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存储引擎流程

  1. 实现 SessionHandlerInterface 接口
  2. 使用 Workerman\Protocols\Http\Session::handlerClass($class_name, $config) 方法替换底层SessionHandler接口

实现 SessionHandlerInterface 接口

自定义session存储驱动须实现 SessionHandlerInterface 接口。这个接口包含以下方法:

  1. SessionHandlerInterface {
  2. /* Methods */
  3. abstract public read ( string $session_id ) : string
  4. abstract public write ( string $session_id , string $session_data ) : bool
  5. abstract public destroy ( string $session_id ) : bool
  6. abstract public gc ( int $maxlifetime ) : int
  7. abstract public close ( void ) : bool
  8. abstract public open ( string $save_path , string $session_name ) : bool
  9. }

SessionHandlerInterface 说明

  • read方法用来从存储中读取session_id对应的所有session数据。请不要对数据进行反序列化操作,框架会自动完成。
  • write方法用来向存储写入session_id对应的session数据。请不要对数据进行序列化操作,框架已经自动完成。
  • destroy方法用来销毁session_id对应的session数据。
  • gc方法用来删除过期的session数据,存储应该对最后修改时间大于maxlifetime的所有session执行删除操作
  • close 无需任何操作,直接返回true即可
  • open 无需任何操作,直接返回true接口

替换底层驱动

实现完SessionHandlerInterface接口后,使用以下方法更改session底层驱动。

  1. Workerman\Protocols\Http\Session::handlerClass($class_name, $config);
  • $class_name 为实现SessionHandlerInterface接口的SessionHandler类的名字。如果有命名空间则需要带上完整的命名空间
  • $config 为SessionHandler类的构造函数的参数

具体实现

注意,这个MySessionHandler类仅仅为了说明更改session底层驱动的流程,MySessionHandler并不能用于生产环境。

  1. <?php
  2. use Workerman\Worker;
  3. use Workerman\Protocols\Http\Session;
  4. use Workerman\Connection\TcpConnection;
  5. use Workerman\Protocols\Http\Request;
  6. require_once __DIR__ . '/vendor/autoload.php';
  7. $worker = new Worker('http://0.0.0.0:8080');
  8. class MySessionHandler implements SessionHandlerInterface
  9. {
  10. protected static $store = [];
  11. public function __construct($config) {
  12. // ['host' => 'localhost']
  13. var_dump($config);
  14. }
  15. public function open($save_path, $name)
  16. {
  17. return true;
  18. }
  19. public function read($session_id)
  20. {
  21. return isset(static::$store[$session_id]) ? static::$store[$session_id]['content'] : '';
  22. }
  23. public function write($session_id, $session_data)
  24. {
  25. static::$store[$session_id] = ['content' => $session_data, 'timestamp' => time()];
  26. }
  27. public function close()
  28. {
  29. return true;
  30. }
  31. public function destroy($session_id)
  32. {
  33. unset(static::$store[$session_id]);
  34. return true;
  35. }
  36. public function gc($maxlifetime) {
  37. $time_now = time();
  38. foreach (static::$store as $session_id => $info) {
  39. if ($time_now - $info['timestamp'] > $maxlifetime) {
  40. unset(static::$store[$session_id]);
  41. }
  42. }
  43. }
  44. }
  45. // 假设新实现的SessionHandler类需要一些配置传入
  46. $config = ['host' => 'localhost'];
  47. // 使用 Workerman\Protocols\Http\Session::handlerClass($class_name, $config) 来更改session底层驱动类
  48. Session::handlerClass(MySessionHandler::class, $config);
  49. $worker->onMessage = function(TcpConnection $connection, Request $request)
  50. {
  51. $session = $request->session();
  52. $session->set('somekey', rand());
  53. $connection->send($session->get('somekey'));
  54. };
  55. Worker::runAll();