คำอธิบาย

workerman ได้เสริมการสนับสนุนบริการ HTTP ตั้งแต่เวอร์ชัน 4.x โดยแนะนำคลาสสำหรับการร้องขอ คลาสสำหรับการตอบสนอง คลาส session รวมถึง SSE หากคุณต้องการใช้บริการ HTTP ของ workerman แนะนำอย่างยิ่งให้ใช้ workerman 4.x หรือเวอร์ชันที่สูงกว่านั้น

โปรดทราบว่าวิธีการต่อไปนี้เป็นวิธีการสำหรับ workerman 4.x ซึ่งไม่เข้ากันกับ workerman 3.x

การเปลี่ยนเครื่องมือเก็บ session

workerman มีเครื่องมือเก็บ session สำหรับการเก็บไฟล์และ 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 configuration
$config = [
    'host'     => '127.0.0.1', // พารามิเตอร์ที่จำเป็น
    'port'     => 6379,        // พารามิเตอร์ที่จำเป็น
    'timeout'  => 2,           // พารามิเตอร์ที่เลือกได้
    'auth'     => '******',    // พารามิเตอร์ที่เลือกได้
    'database' => 1,           // พารามิเตอร์ที่เลือกได้
    'prefix'   => 'session_'   // พารามิเตอร์ที่เลือกได้
];
// ใช้ Workerman\Protocols\Http\Session::handlerClass เพื่อเปลี่ยนคลาสที่เป็นเบื้องหลังของ session
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

เมื่อใช้เครื่องมือเก็บเริ่มต้น ข้อมูล session จะถูกเก็บในดิสก์โดยตำแหน่งเริ่มต้นอยู่ที่ตำแหน่งที่ส่งคืนโดย 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';

// ตั้งค่าตำแหน่งเก็บไฟล์ session
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();

การทำความสะอาดไฟล์ session

เมื่อใช้เครื่องมือเก็บ session เริ่มต้น จะมีไฟล์ session หลายไฟล์ในดิสก์,
workerman จะลบไฟล์ session ที่หมดอายุออกตามที่ตั้งค่าใน php.ini โดยใช้ตัวเลือก session.gc_probability session.gc_divisor และ session.gc_maxlifetime สำหรับคำอธิบายเกี่ยวกับสามตัวเลือกนี้ โปรดดูที่ คู่มือ php

การเปลี่ยนเครื่องมือเก็บ

นอกจากเครื่องมือเก็บ session แบบไฟล์และเครื่องมือเก็บ session แบบ redis แล้ว workerman ยังอนุญาตให้คุณเพิ่มเครื่องมือเก็บ session ใหม่ผ่าน стандартный SessionHandlerInterface เช่นเครื่องมือเก็บ session แบบ mangoDb หรือเครื่องมือเก็บ session แบบ MySQL

กระบวนการเพิ่มเครื่องมือเก็บ session ใหม่

  1. สร้าง SessionHandlerInterface
  2. ใช้ Workerman\Protocols\Http\Session::handlerClass($class_name, $config) เพื่อแทนที่เครื่องมือเก็บ SessionHandler แบบเบื้องหลัง

การสร้าง SessionHandlerInterface

การสร้างเครื่องมือเก็บ session ที่กำหนดเองต้องใช้การสร้าง SessionHandlerInterface นี่คือเมธอดที่รวมอยู่:

SessionHandlerInterface {
    /* เมธอด */
    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 จากที่จัดเก็บตาม session_id โปรดอย่าทำการย้อนกลับข้อมูล เนื่องจากเฟรมเวิร์กจะทำให้เสร็จโดยอัตโนมัติ
  • เมธอด write ใช้สำหรับเขียนข้อมูล session ไปยังที่จัดเก็บตาม session_id โปรดอย่าทำการจัดเรียงข้อมูล เนื่องจากเฟรมเวิร์กได้ทำให้องค์ประกอบนั้นเสร็จหมดแล้ว
  • เมธอด destroy ใช้สำหรับทำลายข้อมูล session ตาม session_id
  • เมธอด gc ใช้สำหรับลบข้อมูล session ที่หมดอายุ โดยที่พื้นที่จัดเก็บควรทำการลบข้อมูล session ที่มีเวลาที่แก้ไขล่าสุดมากกว่า maxlifetime
  • เมธอด close ไม่ต้องการการดำเนินการใดๆ เพียงแค่ส่งค่ากลับ true
  • เมธอด open ไม่ต้องการการดำเนินการใดๆ เพียงแค่ส่งค่ากลับ true

การแทนที่เครื่องมือเก็บแบบเบื้องหลัง

เมื่อเสร็จสิ้นการสร้าง SessionHandlerInterface แล้ว ให้ใช้วิธีการต่อไปนี้ในการเปลี่ยนเครื่องมือเก็บ session แบบเบื้องหลัง

Workerman\Protocols\Http\Session::handlerClass($class_name, $config);
  • $class_name เป็นชื่อของคลาส SessionHandler ที่ใช้การสร้าง SessionHandlerInterface หากมีการจัดกลุ่มชื่อจะต้องระบุชื่อเต็ม
  • $config เป็นพาระแรกของคอนสตรัคเตอร์ของคลาส SessionHandler

การดำเนินการเฉพาะ

โปรดทราบว่าคลาส MySessionHandler นี้เป็นเพียงเพื่อแสดงกระบวนการเปลี่ยนเครื่องมือเก็บ session แบบเบื้องหลัง 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
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();