我的需求是根據(jù)需求給客戶端某個用戶推送消息,代碼如下:
<?php
use Workerman\Worker;
include_once __DIR__ . DIRECTORY_SEPARATOR . '../config.php';
require_once WORKERMAN_WEBSOCKET_API_ROOT . '/Workerman/Autoloader.php';
require_once ROOT_DIR . 'lib/FileMonitor.php';
include_once ROOT_DIR . 'lib/config.php';
include_once ROOT_DIR . 'lib/MySQL.php';
include_once ROOT_DIR . 'lib/SysException.php';
include_once ROOT_DIR . 'lib/ActionException.php';
include_once ROOT_DIR . 'lib/common.php';
include_once H5_API_ROOT . 'include/function.php';
include_once H5_API_ROOT . 'include/action.php';
include_once H5_API_ROOT . 'include/verifyRequest.php';
//方便監(jiān)控WorkerMan進(jìn)程狀態(tài)
Worker::$pidFile = ROOT_DIR . 'logs/workerman.pid';
//輸出日志, 如echo,var_dump等
Worker::$stdoutFile = ROOT_DIR . 'logs/stdout.log';
//workerman自身相關(guān)的日志,包括啟動、停止等,不包含任何業(yè)務(wù)日志
Worker::$logFile = ROOT_DIR . 'logs/workerman.log';
// 創(chuàng)建一個Worker監(jiān)聽2345端口,使用http協(xié)議通訊
$worker = new Worker('websocket://' . $ws_server_config['host'] . ':' . $ws_server_config['port']);
// 啟動4個進(jìn)程對外提供服務(wù)
$worker->count = 4;
$worker->name = 'MyWebsocketWorker';
// 新增加一個屬性,用來保存uid到connection的映射
$uuidConnections = [];
$worker->onWorkerStart = function ($worker) {
echo "Worker " . $worker->id . " starting...\n";
};
$worker->onConnect = function ($connection) {
echo "new connection " . $connection->worker->id . ' : ' . $connection->id . " from ip " . $connection->getRemoteIp() . "\n";
};
$worker->onMessage = function ($connection, $data) use ($worker) {
$data = parseClientContentToArray($data);
//print_r($data);
if (empty($data['sid'])) {
echo 'sid 參數(shù)缺失' . "\r\n";
return;
}
global $uuidConnections;
$uuidConnections[$data['sid']] = $connection;
print_r(array_keys($uuidConnections));
//require_once 'action.php';
switch ($data['act']) {
case 'push_msg_to_individual':
print_r(array_keys($uuidConnections));
if (isset($uuidConnections[$data['data']['tsid']])) {
$result = $uuidConnections[$data['data']['tsid']]->send($data['data']['content']);
if ($result === true) {
echo "消息發(fā)送成功\r\n";
} else if ($result === false) {
echo "消息發(fā)送失敗\r\n";
} else {
echo "發(fā)生未知錯誤\r\n";
}
} else {
echo "目標(biāo)用戶已下線,消息發(fā)送失敗\r\n";
}
break;
default:
//echo "未匹配到方法\r\n";
break;
}
$connection->send('OK!');
};
$worker->onClose = function ($connection) {
echo "connection " . $connection->id . " closed\n";
};
$worker->onError = function ($connection, $code, $msg) {
echo $connection->id . " error $code $msg\n";
};
// 運(yùn)行worker
Worker::runAll();
我有一個客戶端頁面用的 js websocket 連接著這個服務(wù),代碼就不上了,另外一個測試頁面代碼如下:
sendMessageBySidV1([
'sid' => '111111111',
'gid' => '',
'type' => '',
'errcode' => 0,
'msg' => '給某個用戶推送消息',
'act' => 'push_msg_to_individual',
'data' => ['tsid' => '1624441757325-0.05429327573496745', 'content' => 'hello ??!']
]);
我期望的結(jié)果是我刷新我這個測試頁面會向我的那個客戶端頁面推送消息。
現(xiàn)在的問題是當(dāng)我把 $worker->count 設(shè)置為大于 1 的時候,會有一定的幾率推送消息失敗,設(shè)置為1不會有問題,看下圖:
我知道大概是進(jìn)程的問題,但是我現(xiàn)在那個 $uuidConnections 是個超全局變量吧,難道每個 worker 讀取 $uuidConnections 的值的時候結(jié)果會不一樣嗎?