説明

workermanは4.xバージョンからHTTPサービスのサポートを強化しました。リクエストクラス、レスポンスクラス、セッションクラス、およびSSEを導入しました。workermanのHTTPサービスを使用したい場合は、workerman4.xまたはそれ以降のバージョンを強く推奨します。

以下はすべてworkerman4.xバージョンの使用法であり、workerman3.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はphp.iniで設定されたsession.gc_probabilitysession.gc_divisorsession.gc_maxlifetimeオプションに基づいて、期限切れのセッションファイルをクリーンアップします。これらの三つのオプションについての説明は、phpマニュアルを参照してください。

ストレージドライバの変更

ファイルセッションストレージエンジンおよびredisセッションストレージエンジンの他に、workermanは標準のSessionHandlerInterfaceインターフェースを使用して、新しいセッションストレージエンジンを追加することを許可しています。例えば、MongoDBセッションストレージエンジン、MySQLセッションストレージエンジンなどです。

新しいセッションストレージエンジンを追加する手順

  1. SessionHandlerInterfaceインターフェースを実装します。
  2. Workerman\Protocols\Http\Session::handlerClass($class_name, $config)メソッドを使用して底層のSessionHandlerインターフェースを置き換えます。

SessionHandlerInterfaceインターフェースの実装

カスタムセッションストレージドライバはSessionHandlerInterfaceインターフェースを実装する必要があります。このインターフェースには以下のメソッドが含まれています。

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
}

SessionHandlerInterfaceの説明

  • readメソッドは、ストレージからsession_idに対応するすべてのセッションデータを読み取るために使用されます。データに対してデシリアライズ操作を行わないでください。フレームワークが自動的に完了します。
  • writeメソッドは、ストレージにsession_idに対応するセッションデータを書き込むために使用されます。データに対してシリアライズ操作を行わないでください。フレームワークが自動的に完了します。
  • destroyメソッドは、session_idに対応するセッションデータを破壊します。
  • gcメソッドは、期限切れのセッションデータを削除するために使用され、ストレージは最終変更時間がmaxlifetimeを超えるすべてのセッションを削除する必要があります。
  • closeは何の操作も必要なく、単にtrueを返すだけです。
  • openは何の操作も必要なく、単にtrueを返すだけのインターフェースです。

底層ドライバの置き換え

SessionHandlerInterfaceインターフェースを実装した後、以下のメソッドを使用してセッションの底層ドライバを変更します。

Workerman\Protocols\Http\Session::handlerClass($class_name, $config);
  • $class_nameはSessionHandlerInterfaceインターフェースを実装したSessionHandlerクラスの名前です。名前空間がある場合は完全な名前空間を含める必要があります。
  • $configはSessionHandlerクラスのコンストラクタのパラメータです。

具体的な実装

注意、MySessionHandlerクラスはセッション底層ドライバの変更手順を説明するためのものであり、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();