Giới thiệu

Workerman từ phiên bản 4.x đã tăng cường hỗ trợ cho dịch vụ HTTP. Nó giới thiệu các lớp yêu cầu, lớp phản hồi, lớp phiên và SSE. Nếu bạn muốn sử dụng dịch vụ HTTP của Workerman, chúng tôi rất khuyến nghị bạn sử dụng Workerman 4.x hoặc phiên bản cao hơn.

Xin lưu ý rằng tất cả các cách sử dụng dưới đây đều dành cho phiên bản Workerman 4.x, không tương thích với Workerman 3.x.

Thay đổi động cơ lưu trữ phiên

Workerman cung cấp động cơ lưu trữ phiên tệp và động cơ lưu trữ redis cho phiên. Mặc định sử dụng động cơ lưu trữ tệp. Nếu bạn muốn thay đổi sang động cơ lưu trữ redis, vui lòng tham khảo mã dưới đây.

<?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');

// cấu hình redis
$config = [
    'host'     => '127.0.0.1', // Tham số bắt buộc
    'port'     => 6379,        // Tham số bắt buộc
    'timeout'  => 2,           // Tham số tùy chọn
    'auth'     => '******',    // Tham số tùy chọn
    'database' => 1,           // Tham số tùy chọn
    'prefix'   => 'session_'   // Tham số tùy chọn
];
// Sử dụng phương thức Workerman\Protocols\Http\Session::handlerClass để thay đổi lớp điều khiển nền của phiên
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();

Thiết lập vị trí lưu trữ phiên

Khi sử dụng động cơ lưu trữ mặc định, dữ liệu phiên sẽ được lưu trữ trên đĩa, vị trí mặc định là vị trí trả về của session_save_path().
Bạn có thể sử dụng phương pháp sau để thay đổi vị trí lưu trữ.

use Workerman\Worker;
use \Workerman\Protocols\Http\Session\FileSessionHandler;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';

// Thiết lập vị trí lưu trữ tệp phiên
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'));
};

// Chạy worker
Worker::runAll();

Dọn dẹp tệp phiên

Khi sử dụng động cơ lưu trữ phiên mặc định, sẽ có nhiều tệp phiên trên đĩa,
Workerman sẽ dọn dẹp các tệp phiên đã hết hạn dựa trên các tùy chọn session.gc_probability, session.gc_divisor, session.gc_maxlifetime được thiết lập trong php.ini. Về ba tùy chọn này, xin xem tài liệu php

Thay đổi động cơ lưu trữ

Ngoài động cơ lưu trữ phiên tệp và động cơ lưu trữ phiên redis, Workerman cho phép bạn thêm các động cơ lưu trữ phiên mới thông qua giao diện tiêu chuẩn SessionHandlerInterface, chẳng hạn như động cơ lưu trữ phiên MongoDB, động cơ lưu trữ phiên MySQL, v.v.

Quy trình thêm động cơ lưu trữ phiên mới

  1. Thực hiện giao diện SessionHandlerInterface
  2. Sử dụng phương thức Workerman\Protocols\Http\Session::handlerClass($class_name, $config) để thay thế giao diện SessionHandler nền

Thực hiện giao diện SessionHandlerInterface

Để tùy chỉnh động cơ lưu trữ phiên, bạn cần thực hiện giao diện SessionHandlerInterface. Giao diện này bao gồm các phương thức sau:

SessionHandlerInterface {
    /* Phương thức */
    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
}

Giải thích về SessionHandlerInterface

  • Phương thức read dùng để đọc tất cả dữ liệu phiên tương ứng với session_id từ lưu trữ. Xin đừng thực hiện thao tác giải mã dữ liệu, khung sẽ tự động hoàn thành.
  • Phương thức write dùng để ghi dữ liệu phiên tương ứng với session_id vào lưu trữ. Xin đừng thực hiện thao tác mã hóa dữ liệu, khung đã hoàn thành tự động.
  • Phương thức destroy dùng để hủy bỏ dữ liệu phiên tương ứng với session_id.
  • Phương thức gc dùng để xóa dữ liệu phiên đã hết hạn, lưu trữ nên thực hiện thao tác xóa đối với tất cả phiên có thời gian sửa đổi cuối lớn hơn maxlifetime
  • close không cần thực hiện thao tác nào, chỉ cần trả về true
  • open không cần thực hiện thao tác nào, chỉ cần trả về true

Thay thế động cơ nền

Sau khi thực hiện giao diện SessionHandlerInterface, sử dụng phương pháp sau để thay đổi động cơ lưu trữ phiên.

Workerman\Protocols\Http\Session::handlerClass($class_name, $config);
  • $class_name là tên lớp SessionHandler thực hiện giao diện SessionHandlerInterface. Nếu có không gian tên thì cần bao gồm cả không gian tên đầy đủ
  • $config là tham số của hàm khởi tạo lớp SessionHandler

Thực hiện cụ thể

Xin lưu ý, lớp MySessionHandler này chỉ để minh họa quy trình thay đổi động cơ lưu trữ phiên, MySessionHandler không thể sử dụng trong môi trường sản xuất.

<?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]);
            }
        }
    }
}

// Giả sử lớp SessionHandler mới được thực hiện cần một số cấu hình được truyền vào
$config = ['host' => 'localhost'];
// Sử dụng Workerman\Protocols\Http\Session::handlerClass($class_name, $config) để thay đổi động cơ lưu trữ nền của phiên
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();