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.
zhishifufei_php/application/push/controller/KefuHandler.php

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);
}
}
}