<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// workerコンテナを初期化し、1234ポートをリッスンします
$worker = new Worker('websocket://workerman.net:1234');
// ====ここでプロセス数は1に設定しなければなりません====
$worker->count = 1;
// uidと接続のマッピングを保存するためのプロパティを追加します(uidはユーザーIDまたはクライアントの一意の識別子です)
$worker->uidConnections = array();
// クライアントからメッセージが届いた時に実行されるコールバック関数
$worker->onMessage = function (TcpConnection $connection, $data) {
global $worker;
// 現在のクライアントが既に認証されているかどうかを判断します、つまりuidが設定されているかどうかです
if (!isset($connection->uid)) {
// 認証されていない場合、最初のパケットをuidとして扱います(ここではデモのため、本当の検証は行っていません)
$connection->uid = $data;
/* uidを接続にマッピングして保存することで、uidで接続を簡単に検索できるようになります。
* 特定のuidにデータを送信することができます
*/
$worker->uidConnections[$connection->uid] = $connection;
return $connection->send('login success, your uid is ' . $connection->uid);
}
// その他のロジック、特定のuidへの送信またはグローバルブロードキャスト
// メッセージのフォーマットがuid:messageの場合は、uidにmessageを送信するものとします
// uidがallの場合はグローバルブロードキャストです
list($recv_uid, $message) = explode(':', $data);
// グローバルブロードキャスト
if ($recv_uid == 'all') {
broadcast($message);
}
// 特定のuidに送信
else {
sendMessageByUid($recv_uid, $message);
}
};
// クライアントが切断された場合
$worker->onClose = function (TcpConnection $connection) {
global $worker;
if (isset($connection->uid)) {
// 接続が切断されたらマッピングを削除します
unset($worker->uidConnections[$connection->uid]);
}
};
// 認証されたすべてのユーザーにデータを送信します
function broadcast($message) {
global $worker;
foreach ($worker->uidConnections as $connection) {
$connection->send($message);
}
}
// uidにデータを送信します
function sendMessageByUid($uid, $message) {
global $worker;
if (isset($worker->uidConnections[$uid])) {
$connection = $worker->uidConnections[$uid];
$connection->send($message);
}
}
// すべてのworkerを実行します(実際には1つのみが定義されています)
Worker::runAll();