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