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.
289 lines
7.8 KiB
289 lines
7.8 KiB
9 months ago
|
<?php
|
||
|
|
||
|
namespace app\push\controller;
|
||
|
|
||
|
use Exception;
|
||
|
use GatewayWorker\Lib\Gateway;
|
||
|
use think\Log;
|
||
|
use service\JwtService;
|
||
|
use app\admin\model\user\User as UserModel;
|
||
|
use app\kefu\model\KefuChatLogModel;
|
||
|
use app\kefu\model\KefuModel;
|
||
|
use app\kefu\services\KefuChatService;
|
||
|
use app\kefu\services\KefuRecordService;
|
||
|
|
||
|
class KefuHandler
|
||
|
{
|
||
|
/**
|
||
|
* @var array 消息内容
|
||
|
* */
|
||
|
protected $message_data = [
|
||
|
'type' => '',
|
||
|
'message' => '',
|
||
|
];
|
||
|
|
||
|
/**
|
||
|
* @var string 消息类型
|
||
|
* */
|
||
|
protected $message_type = '';
|
||
|
|
||
|
/**
|
||
|
* @var string $client_id
|
||
|
* */
|
||
|
protected $client_id = '';
|
||
|
|
||
|
/**
|
||
|
* @var int 当前登陆用户
|
||
|
* */
|
||
|
protected $uid = null;
|
||
|
|
||
|
protected $isKefu = false;
|
||
|
|
||
|
/**
|
||
|
* @var null 本类实例化结果
|
||
|
* */
|
||
|
protected static $instance = null;
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* */
|
||
|
protected function __construct($message_data = [])
|
||
|
{
|
||
|
}
|
||
|
|
||
|
protected $methodWhiteList = [
|
||
|
"ping",
|
||
|
"kefu_login",
|
||
|
"user_login"
|
||
|
];
|
||
|
|
||
|
/**
|
||
|
* 实例化本类
|
||
|
* */
|
||
|
public static function instance()
|
||
|
{
|
||
|
if (is_null(self::$instance)) self::$instance = new static();
|
||
|
return self::$instance;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 开始设置回调
|
||
|
* @param string $typeFnName 回调函数名
|
||
|
* @param string $client_id
|
||
|
* @param array $message_data
|
||
|
*
|
||
|
* */
|
||
|
public function start($typeFnName, $client_id, $message_data)
|
||
|
{
|
||
|
$this->message_type = $typeFnName;
|
||
|
$this->message_data = $message_data;
|
||
|
$this->client_id = $client_id;
|
||
|
$session_data = Gateway::getSession($client_id);
|
||
|
|
||
|
if (!$session_data || !is_array($session_data)) {
|
||
|
$this->isKefu = false;
|
||
|
} else {
|
||
|
if (isset($session_data['is_kefu'])) {
|
||
|
$this->isKefu = $session_data['is_kefu'] == 1;
|
||
|
}
|
||
|
if (isset($session_data['uid'])) {
|
||
|
$this->uid = $session_data['uid'];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (method_exists($this, $typeFnName)) {
|
||
|
if (in_array($typeFnName, $this->methodWhiteList) || $this->uid) {
|
||
|
// 如果是免登录方法或者已登录,则执行相应函数
|
||
|
call_user_func([$this, $typeFnName]);
|
||
|
} else {
|
||
|
// 否则断开连接
|
||
|
Gateway::closeClient($client_id);
|
||
|
}
|
||
|
} else {
|
||
|
throw new \Exception('缺少回调方法' . $typeFnName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 心跳检测
|
||
|
*
|
||
|
* */
|
||
|
protected function ping()
|
||
|
{
|
||
|
Gateway::sendToClient($this->client_id, json_encode(['type' => 'ping', 'data' => 'ok']));
|
||
|
}
|
||
|
|
||
|
protected function kefu_login()
|
||
|
{
|
||
|
$token = $this->message_data['data'];
|
||
|
|
||
|
$jwtService = new JwtService("kefu");
|
||
|
|
||
|
try {
|
||
|
$kefuId = $jwtService->parseToken($token);
|
||
|
$jwtService->verifyToken();
|
||
|
|
||
|
Gateway::setSession($this->client_id, [
|
||
|
'is_kefu' => 1,
|
||
|
'uid' => $kefuId
|
||
|
]);
|
||
|
|
||
|
|
||
|
Gateway::bindUid($this->client_id, "kefu" . (string)$kefuId);
|
||
|
|
||
|
Gateway::sendToClient($this->client_id, json_encode(['type' => 'login_success']));
|
||
|
|
||
|
(new KefuRecordService)->saveUserOnlineStatus($kefuId, true, true);
|
||
|
} catch (Exception $e) {
|
||
|
// 未通过鉴权,断开连接
|
||
|
|
||
|
Gateway::sendToClient($this->client_id, json_encode(['type' => 'login_fail']));
|
||
|
sleep(1);
|
||
|
Gateway::closeClient($this->client_id);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected function chat()
|
||
|
{
|
||
|
$data = $this->message_data['data'];
|
||
|
|
||
|
$chatService = new KefuChatService;
|
||
|
|
||
|
$is_tourist = isset($data['is_tourist']) ? $data['is_tourist'] : 0;
|
||
|
$type = isset($data['type']) ? $data['type'] : 0;
|
||
|
$attach_type = isset($data['attach_type']) ? $data['attach_type'] : 0;
|
||
|
|
||
|
|
||
|
$chatResponse = $chatService->saveChatLog($data['msn'], $this->uid, $data['to_uid'], $is_tourist, (int)$this->isKefu, $data['msn_type'], $type, $attach_type);
|
||
|
|
||
|
(new KefuRecordService)->saveUserRecord($this->uid, $data['to_uid'], $this->isKefu, $data['msn_type'], $data['msn'], $type);
|
||
|
|
||
|
$senderUid = ($this->isKefu ? 'kefu' : 'user') . (string)$this->uid;
|
||
|
$recverUid = ($this->isKefu ? 'user' : 'kefu') . (string)$data['to_uid'];
|
||
|
|
||
|
Gateway::sendToUid($senderUid, json_encode([
|
||
|
'type' => 'chat',
|
||
|
'data' => $chatResponse
|
||
|
]));
|
||
|
|
||
|
|
||
|
Gateway::sendToUid($recverUid, json_encode([
|
||
|
'type' => 'chat',
|
||
|
'data' => $chatResponse
|
||
|
]));
|
||
|
|
||
|
if (!$this->isKefu) {
|
||
|
$all_kefu_uids = Gateway::getSession($this->client_id)['chat_kefu_uid'];
|
||
|
|
||
|
if (!in_array($recverUid, $all_kefu_uids)) {
|
||
|
$all_kefu_uids[] = $recverUid;
|
||
|
Gateway::updateSession($this->client_id, [
|
||
|
'chat_kefu_uid' => $all_kefu_uids
|
||
|
]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected function online()
|
||
|
{
|
||
|
$data = $this->message_data['data'];
|
||
|
$is_online = $data['online'];
|
||
|
|
||
|
(new KefuRecordService)->saveUserOnlineStatus($this->uid, $is_online, $this->isKefu);
|
||
|
|
||
|
$recvUid = ($this->isKefu ? 'kefu' : 'user') . $this->uid;
|
||
|
|
||
|
Gateway::sendToUid($recvUid, json_encode([
|
||
|
'type' => 'offline',
|
||
|
'data' => [
|
||
|
'self' => true
|
||
|
]
|
||
|
]));
|
||
|
}
|
||
|
|
||
|
protected function request_transfer()
|
||
|
{
|
||
|
$data = $this->message_data['data'];
|
||
|
|
||
|
$kefuUserInfo = KefuModel::get($this->uid);
|
||
|
|
||
|
Gateway::sendToUid('kefu' . $data['kefu_id'], json_encode([
|
||
|
'type' => 'request_transfer',
|
||
|
'data' => [
|
||
|
'nickname' => $kefuUserInfo->nickname,
|
||
|
'kefu_id' => $this->uid,
|
||
|
'uid' => $data['uid']
|
||
|
]
|
||
|
]));
|
||
|
}
|
||
|
|
||
|
protected function accept_transfer()
|
||
|
{
|
||
|
$data = $this->message_data['data'];
|
||
|
|
||
|
$kefuUserInfo = KefuModel::get($this->uid);
|
||
|
|
||
|
Gateway::sendToUid('kefu' . $data['kefu_id'], json_encode([
|
||
|
'type' => 'accept_transfer',
|
||
|
'data' => [
|
||
|
'nickname' => $kefuUserInfo->nickname,
|
||
|
'kefu_id' => $this->uid,
|
||
|
'uid' => $data['uid']
|
||
|
]
|
||
|
]));
|
||
|
|
||
|
Gateway::sendToUid("user" . $data['uid'], json_encode([
|
||
|
'type' => 'transfer',
|
||
|
'data' => [
|
||
|
'kefu_id' => $this->uid
|
||
|
]
|
||
|
]));
|
||
|
}
|
||
|
|
||
|
protected function reject_transfer()
|
||
|
{
|
||
|
$data = $this->message_data['data'];
|
||
|
|
||
|
$kefuUserInfo = KefuModel::get($this->uid);
|
||
|
|
||
|
Gateway::sendToUid('kefu' . $data['kefu_id'], json_encode([
|
||
|
'type' => 'reject_transfer',
|
||
|
'data' => [
|
||
|
'nickname' => $kefuUserInfo->nickname,
|
||
|
'kefu_id' => $this->uid,
|
||
|
'uid' => $data['uid']
|
||
|
]
|
||
|
]));
|
||
|
}
|
||
|
|
||
|
protected function user_login()
|
||
|
{
|
||
|
$token = $this->message_data['data'];
|
||
|
|
||
|
$jwtService = new JwtService();
|
||
|
|
||
|
try {
|
||
|
$uid = $jwtService->parseToken($token);
|
||
|
$jwtService->verifyToken();
|
||
|
|
||
|
Gateway::setSession($this->client_id, [
|
||
|
'is_kefu' => 0,
|
||
|
'uid' => $uid,
|
||
|
'chat_kefu_uid' => []
|
||
|
]);
|
||
|
|
||
|
Gateway::bindUid($this->client_id, "user" . (string)$uid);
|
||
|
|
||
|
Gateway::sendToClient($this->client_id, json_encode(['type' => 'login_success']));
|
||
|
|
||
|
(new KefuRecordService)->saveUserOnlineStatus($uid, true, false);
|
||
|
} catch (Exception $e) {
|
||
|
// 未通过鉴权,断开连接
|
||
|
|
||
|
Gateway::sendToClient($this->client_id, json_encode(['type' => 'login_fail']));
|
||
|
sleep(1);
|
||
|
Gateway::closeClient($this->client_id);
|
||
|
}
|
||
|
}
|
||
|
}
|