ฟังก์ชันสร้าง (__construct)
คำอธิบาย:
Worker::__construct([string $listen , array $context])
เริ่มต้นการทำงานของ Worker สามารถตั้งค่าคุณสมบัติและ callback ของ container เพื่อให้ทำงานตามฟังก์ชันที่กำหนด
พารามิเตอร์
$listen (พารามิเตอร์ที่เลือกได้ หากไม่กำหนดจะหมายถึงไม่ฟังที่พอร์ตใดๆ)
ถ้ากำหนดพารามิเตอร์ $listen จะทำการฟัง socket.
รูปแบบของ $listen คือ <โปรโตคอล>://<ที่อยู่การฟัง>
<โปรโตคอล> สามารถเป็นรูปแบบต่อไปนี้:
tcp: เช่น tcp://0.0.0.0:8686
udp: เช่น udp://0.0.0.0:8686
unix: เช่น unix:///tmp/my_file (ต้องการ Workerman>=3.2.7)
http: เช่น http://0.0.0.0:80
websocket: เช่น websocket://0.0.0.0:8686
text: เช่น text://0.0.0.0:8686 (text เป็นโปรโตคอลข้อความในตัว Workerman รองรับ telnet ดูรายละเอียดในภาคผนวกส่วนโปรโตคอลข้อความ)
และโปรโตคอลที่กำหนดเองอื่น ๆ ดูในเอกสารนี้สำหรับการปรับแต่งโปรโตคอลการสื่อสาร
<ที่อยู่การฟัง> สามารถเป็นรูปแบบต่อไปนี้:
ถ้าเป็นยูนิกซ์ซ็อกเก็ต ที่อยู่จะเป็นเส้นทางของดิสก์ท้องถิ่น
ซ็อกเก็ตที่ไม่ใช่ยูนิกซ์ ที่อยู่รูปแบบจะเป็น <IP เครื่อง> : <หมายเลขพอร์ต>
<IP เครื่อง> สามารถเป็น 0.0.0.0 หมายถึงฟังทั้งหมดของการเชื่อมต่อ รวมถึง IP ในเครือข่ายในประเทศและ IP สาธารณะ รวมถึงลูปกลับในท้องถิ่น 127.0.0.1
<IP เครื่อง> หากเป็น 127.0.0.1 จะหมายถึงการฟังจากลูปกลับในท้องถิ่น สามารถเข้าถึงได้เฉพาะจากเครื่องเท่านั้น ไม่สามารถเข้าถึงจากภายนอกได้
<IP เครื่อง> หากเป็น IP ในเครือข่ายในประเทศ เช่น 192.168.xx.xx จะหมายถึงการฟังเฉพาะ IP ในเครือข่ายภายใน ดังนั้นผู้ใช้งานจากภายนอกไม่สามารถเข้าถึงได้
<IP เครื่อง> ที่กำหนดค่าหากไม่เป็น IP เครื่องจะไม่สามารถทำการฟังได้ และจะได้รับข้อความผิดพลาด Cannot assign requested address
ข้อควรระวัง: <หมายเลขพอร์ต> ไม่สามารถมากกว่า 65535 ได้.<หมายเลขพอร์ต> หากน้อยกว่า 1024 จะต้องมีสิทธิ์ root เพื่อทำการฟัง. หมายเลขพอร์ตที่ฟังจะต้องเป็นหมายเลขพอร์ตที่ยังไม่ได้ถูกใช้งาน มิฉะนั้นจะไม่สามารถฟังได้ และจะได้รับข้อความผิดพลาด Address already in use
$context
เป็นอาเรย์ ใช้สำหรับส่งผ่านตัวเลือกบริบทของซ็อกเก็ต ดูที่ ตัวเลือกบริบทของซ็อกเก็ต
ตัวอย่าง
Worker เป็น container สำหรับ http เพื่อฟังและจัดการคำขอ http
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8686');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$connection->send("hello");
};
// รัน worker
Worker::runAll();
Worker เป็น container สำหรับ websocket เพื่อฟังและจัดการคำขอ websocket
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('websocket://0.0.0.0:8686');
$worker->onMessage = function(TcpConnection $connection, $data)
{
$connection->send("hello");
};
// รัน worker
Worker::runAll();
Worker เป็น container สำหรับ tcp เพื่อฟังและจัดการคำขอ tcp
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('tcp://0.0.0.0:8686');
$worker->onMessage = function(TcpConnection $connection, $data)
{
$connection->send("hello");
};
// รัน worker
Worker::runAll();
Worker เป็น container สำหรับ udp เพื่อฟังและจัดการคำขอ udp
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('udp://0.0.0.0:8686');
$worker->onMessage = function(TcpConnection $connection, $data)
{
$connection->send("hello");
};
// รัน worker
Worker::runAll();
Worker ฟังจากซ็อกเก็ตโดเมนยูนิกซ์ (ต้องการ Workerman เวอร์ชัน>=3.2.7)
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('unix:///tmp/my.sock');
$worker->onMessage = function(TcpConnection $connection, $data)
{
$connection->send("hello");
};
// รัน worker
Worker::runAll();
Worker container โดยไม่ฟังที่ใด ๆ เพื่อจัดการบางงานตามตารางเวลา
use \Workerman\Worker;
use \Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$task = new Worker();
$task->onWorkerStart = function($task)
{
// ทำงานทุก 2.5 วินาที
$time_interval = 2.5;
Timer::add($time_interval, function()
{
echo "task run\n";
});
};
// รัน worker
Worker::runAll();
Worker ฟังจากพอร์ตโปรโตคอลที่กำหนดเอง
โครงสร้างไดเรกทอรีสุดท้าย
├── Protocols // นี่คือไดเรกทอรี Protocols ที่จะสร้าง
│ └── MyTextProtocol.php // ไฟล์โปรโตคอลที่กำหนดเองที่จะสร้าง
├── test.php // สคริปต์ทดสอบที่สร้าง
└── Workerman // ไดเรกทอรีซอร์สโค้ดของ Workerman ไม่ต้องแก้ไขภายใน
- สร้างไดเรกทอรี Protocols และสร้างไฟล์โปรโตคอล
Protocols/MyTextProtocol.php (อ้างอิงจากโครงสร้างไดเรกทอรีด้านบน)
// ชื่อ namespace สำหรับโปรโตคอลที่กำหนดเองของผู้ใช้แต่ละคนถูกตั้งเป็น Protocols
namespace Protocols;
// โปรโตคอลข้อความง่าย รูปแบบโปรโตคอลคือ ข้อความ + การขึ้นบรรทัดใหม่
class MyTextProtocol
{
// ฟังก์ชันการแบ่งแพ็คเกจ คืนค่าความยาวของแพ็คเกจในปัจจุบัน
public static function input($recv_buffer)
{
// ค้นหาสัญลักษณ์การขึ้นบรรทัด
$pos = strpos($recv_buffer, "\n");
// ถ้าไม่พบสัญลักษณ์การขึ้นบรรทัด แสดงว่าไม่ใช่แพ็คเกจที่สมบูรณ์ คืนค่า 0 รอคอยข้อมูลต่อไป
if($pos === false)
{
return 0;
}
// พบสัญลักษณ์การขึ้นบรรทัด คืนค่าความยาวของแพ็คเกจในปัจจุบัน รวมถึงสัญลักษณ์การขึ้นบรรทัด
return $pos+1;
}
// เมื่อได้รับแพ็คเกจที่สมบูรณ์แล้วจะทำการ decode โดยอัตโนมัติที่นี่เพียงแค่ trim สัญลักษณ์การขึ้นบรรทัด
public static function decode($recv_buffer)
{
return trim($recv_buffer);
}
// ข้อมูลก่อนที่จะส่งให้กับลูกค้าจะถูกเข้ารหัสด้วย encode โดยอัตโนมัติ แล้วส่งไปยังลูกค้า ที่นี่จะแทรกการขึ้นบรรทัด
public static function encode($data)
{
return $data."\n";
}
}
- ใช้โปรโตคอล MyTextProtocol ในการฟังและจัดการคำขอ
สร้างไฟล์ test.php ตามโครงสร้างไดเรกทอรีสุดท้ายข้างต้น
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// #### MyTextProtocol worker ####
$text_worker = new Worker("MyTextProtocol://0.0.0.0:5678");
/*
* เมื่อได้รับข้อมูลที่สมบูรณ์ (จบด้วยการขึ้นบรรทัด) จะทำการเรียกใช้ MyTextProtocol::decode('ข้อมูลที่ได้รับ')
* ผลลัพธ์จะถูกส่งผ่านให้กับการ callback onMessage
*/
$text_worker->onMessage = function(TcpConnection $connection, $data)
{
var_dump($data);
/*
* การส่งข้อมูลไปยังลูกค้าจะเรียก MyTextProtocol::encode('hello world') เพื่อทำการเข้ารหัสโปรโตคอลโดยอัตโนมัติ
* จากนั้นส่งไปยังลูกค้า
*/
$connection->send("hello world");
};
// รัน worker ทั้งหมด
Worker::runAll();
- ทดสอบ
เปิดเทอร์มินัล เข้าสู่ไดเรกทอรีที่มี test.php และรันคำสั่ง php test.php start
php test.php start
Workerman[test.php] start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.2.7 PHP version:5.4.37
------------------------ WORKERS -------------------------------
user worker listen processes status
root none myTextProtocol://0.0.0.0:5678 1 [OK]
----------------------------------------------------------------
Press Ctrl-C to quit. Start success.
เปิดเทอร์มินัลและใช้ telnet ทดสอบ (แนะนำให้ใช้ telnet บนระบบลินุกซ์)
สมมุติว่าทดสอบจากเครื่องของคุณ
รันคำสั่งในเทอร์มินัล telnet 127.0.0.1 5678
จากนั้นพิมพ์ hi แล้วกด Enter
คุณจะได้รับข้อมูล hello world\n
telnet 127.0.0.1 5678
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
hi
hello world