You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

170 lines
5.5 KiB

<?php
namespace addons\shopro\library\chat;
/**
* This file is part of workerman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* 用于检测业务代码死循环或者长时间阻塞等问题
* 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload
* 然后观察一段时间workerman.log看是否有process_timeout异常
*/
//declare(ticks=1);
use GatewayWorker\Lib\Gateway;
use Workerman\Lib\Timer;
/**
* 主逻辑
* 主要是处理 onConnect onMessage onClose 三个方法
* onConnect 和 onClose 如果不需要可以不用实现并删除
*/
class Events
{
public static function onWorkerStart($businessWorker)
{
// 5 秒同步一下 客服当前接待客户数,计算客服忙碌度
Timer::add(5, function () {
// 获取当前连接的客服
$clientIds = Gateway::getClientIdListByGroup(Online::getGrouponName('online_customer_service'));
foreach ($clientIds as $client_id) {
$session = Gateway::getSession($client_id);
$customerService = $session['user'];
$customer_service_id = $session['uid'] ?? 0; // 客服 id
if ($customer_service_id) {
// 当前客服分组名
$customerServiceGroupName = Online::getGrouponName('customer_service_user', ['customer_service_id' => $customer_service_id]);
// 获取并设置当前客服正在服务的用户
$customerService['current_num'] = Gateway::getClientIdCountByGroup($customerServiceGroupName);
$max_num = $customerService['max_num'] > 0 ? $customerService['max_num'] : 1; // 避免除数为 0
$customerService['busy_percent'] = $customerService['current_num'] / $max_num; // 繁忙程度,越大越繁忙
Gateway::updateSession($client_id, ['user' => $customerService]);
}
}
});
// 初始化上传配置
Online::uploadConfigInit();
}
public static function onWebSocketConnect($client_id, $data)
{
// 存储当前请求信息
$_SESSION['server'] = $data['server'] ?? [];
$request = $data['get'];
$linkerData = [];
$linkerData['identify'] = $request['identify'] ?? '';
$linkerData['session_id'] = $request['session_id'] ?? '';
$linkerData['token'] = $request['token'] ?? '';
$linkerData['expire_time'] = $request['expire_time'] ?? '';
$linkerData['customer_service_id'] = $request['customer_service_id'] ?? 0;
if (empty($linkerData['identify'])) {
// 缺少参数
Sender::error($client_id, [
'type' => 'connect_error',
'msg' => '连接错误'
]);
Gateway::closeClient($client_id);
return false;
}
// 连接者
$linker = new Linker($client_id, $linkerData);
if ($linker->checkAndBind()) {
// init
$linker->init();
}
}
/**
* 当客户端发来消息时触发
* @param int $client_id 连接id
* @param mixed $message 具体消息
*/
public static function onMessage($client_id, $requestData)
{
$requestData = json_decode($requestData, true);
$identify = $_SESSION['identify'] ?? '';
$type = $requestData['type'] ?? ''; // 消息类型
$data = $requestData['data'] ?? []; // 要做的事件,参数
$message = $requestData['message'] ?? []; // 发送的消息
if (empty($type) || empty($identify)) {
// 缺少参数
Sender::error($client_id, [
'type' => 'params_error',
'msg' => '参数错误'
]);
Gateway::closeClient($client_id);
return false;
}
if ($type == 'ping') {
// 心跳检测,直接返回
return true;
}
if ($identify == 'customer_service') {
$session_id = $requestData['session_id'] ?? ''; // 如果是客服,接受传入的 session_id
} else {
$session_id = $_SESSION['uid'] ?? '';
}
$linkerData = [
'identify' => $identify,
];
// 连接者
$linker = new Linker($client_id, $linkerData);
$linker->message($session_id, $type, $message, $data);
}
/**
* 当用户断开连接时触发
* @param int $client_id 连接id
*/
public static function onClose($client_id)
{
$identify = $_SESSION['identify'] ?? '';
if (empty($identify)) {
// 缺少参数
Sender::error($client_id, [
'type' => 'params_error',
'msg' => '参数错误'
]);
Gateway::closeClient($client_id);
return false;
}
// 只能通过 $identify 获取 session
$linkerData = [
'identify' => $identify,
];
// 连接者
$linker = new Linker($client_id, $linkerData);
$linker->close($client_id);
}
}