ตัวอย่างที่ 1
(ต้องการเวอร์ชัน Workerman >= 3.3.0)
ระบบการส่งข้อมูลแบบกลุ่มหลายกระบวนการที่อิงจาก Worker
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$channel_server = new Channel\Server('0.0.0.0', 2206);
$worker = new Worker('websocket://0.0.0.0:1234');
$worker->count = 8;
// อาร์เรย์แมพเชื่อมต่อกับกลุ่มทั่วโลก
$group_con_map = array();
$worker->onWorkerStart = function(){
// Client ของ Channel เชื่อมต่อกับ Server ของ Channel
Channel\Client::connect('127.0.0.1', 2206);
// เฝ้าฟังเหตุการณ์ส่งข้อความไปยังกลุ่มทั่วโลก
Channel\Client::on('send_to_group', function($event_data){
$group_id = $event_data['group_id'];
$message = $event_data['message'];
global $group_con_map;
var_dump(array_keys($group_con_map));
if (isset($group_con_map[$group_id])) {
foreach ($group_con_map[$group_id] as $con) {
$con->send($message);
}
}
});
};
$worker->onMessage = function(TcpConnection $con, $data){
// ข้อความเข้าร่วมกลุ่ม {"cmd":"add_group", "group_id":"123"}
// หรือ ข้อความเผยแพร่ {"cmd":"send_to_group", "group_id":"123", "message":"นี่คือข้อความ"}
$data = json_decode($data, true);
var_dump($data);
$cmd = $data['cmd'];
$group_id = $data['group_id'];
switch($cmd) {
// เชื่อมต่อเข้ากลุ่ม
case "add_group":
global $group_con_map;
// เพิ่มการเชื่อมต่อไปยังอาร์เรย์กลุ่มที่สอดคล้องกัน
$group_con_map[$group_id][$con->id] = $con;
// บันทึกว่าการเชื่อมต่อนี้เข้ากลุ่มไหนบ้าง เพื่อที่จะทำความสะอาดข้อมูลใน group_con_map เมื่อ onclose
$con->group_id = isset($con->group_id) ? $con->group_id : array();
$con->group_id[$group_id] = $group_id;
break;
// ส่งข้อความให้กลุ่ม
case "send_to_group":
// Channel\Client ส่งข้อความไปยังทุกโปรเซสของทุกเซิร์ฟเวอร์
Channel\Client::publish('send_to_group', array(
'group_id'=>$group_id,
'message'=>$data['message']
));
break;
}
};
// นี่สำคัญมาก ตอนปิดการเชื่อมต่อให้ลบการเชื่อมต่อออกจากข้อมูลกลุ่มทั่วโลกเพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำ
$worker->onClose = function(TcpConnection $con){
global $group_con_map;
// วนลูปผ่านกลุ่มทั้งหมดที่การเชื่อมต่อเข้าร่วม เพื่อลบข้อมูลที่สอดคล้องจาก group_con_map
if (isset($con->group_id)) {
foreach ($con->group_id as $group_id) {
unset($group_con_map[$group_id][$con->id]);
if (empty($group_con_map[$group_id])) {
unset($group_con_map[$group_id]);
}
}
}
};
Worker::runAll();
การทดสอบ (สมมติว่าทำงานบนเครื่องเดียวกัน 127.0.0.1)
- เรียกใช้เซิร์ฟเวอร์
php start.php start Workerman[del.php] เริ่มต้นในโหมด DEBUG ----------------------- WORKERMAN ----------------------------- เวอร์ชัน Workerman:3.4.2 เวอร์ชัน PHP:7.1.3 ------------------------ WORKERS ------------------------------- ผู้ใช้ คนงาน ฟัง สถานะกระบวนการ liliang ChannelServer frame://0.0.0.0:2206 1 [OK] liliang none websocket://0.0.0.0:1234 12 [OK] ---------------------------------------------------------------- กด Ctrl-C เพื่อออก. เริ่มต้นสำเร็จ.
2. ลูกค้าต่อเชื่อมกับเซิร์ฟเวอร์
เปิดเบราว์เซอร์ Chrome กด F12 เปิดคอนโซลการดีบัก ในแถบ Console ให้พิมพ์ (หรือวางโค้ดด้านล่างในหน้า html เพื่อรันด้วย js)
```javascript
// สมมติว่าที่อยู่ IP ของเซิร์ฟเวอร์คือ 127.0.0.1 โปรดเปลี่ยนเป็นที่อยู่ IP จริงของเซิร์ฟเวอร์ในระหว่างการทดสอบ
ws = new WebSocket('ws://127.0.0.1:1234');
ws.onmessage = function(data){console.log(data.data)};
ws.onopen = function() {
ws.send('{"cmd":"add_group", "group_id":"123"}');
ws.send('{"cmd":"send_to_group", "group_id":"123", "message":"นี่คือข้อความ"}');
};