107 lines
3.8 KiB
PHP
107 lines
3.8 KiB
PHP
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Author: ywxapp<admin@ywxapp.cn>
|
|
// +----------------------------------------------------------------------
|
|
declare (strict_types = 1);
|
|
|
|
namespace addon\wxchat\worker\handle;
|
|
|
|
use addon\wxchat\worker\enum\MsgFrame;
|
|
use addon\wxchat\worker\enum\MsgType;
|
|
use addon\wxchat\worker\Message;
|
|
use addon\wxchat\worker\MsgReply;
|
|
use GatewayWorker\Lib\Gateway;
|
|
|
|
/**
|
|
* SystemHandle 类
|
|
*
|
|
* @author ywxapp <admin@ywxapp.cn>
|
|
*/
|
|
class SystemHandle
|
|
{
|
|
|
|
public static function handle($client_id, $header, $payload)
|
|
{
|
|
switch ($header->type) {
|
|
case MsgType::HEARTBEAT->value:
|
|
self::Heartbeat($client_id, $header, $payload);
|
|
break;
|
|
case MsgType::AUTH->value:
|
|
self::Auth($client_id, $header, $payload);
|
|
break;
|
|
case MsgType::NOTICE->value:
|
|
self::Notification($client_id, $header, $payload);
|
|
break;
|
|
default:
|
|
ErrorHandle::sendErrorMsg($client_id, '不支持的系统消息类型');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 心跳响应
|
|
*/
|
|
private static function Heartbeat($client_id, $header, $payload)
|
|
{
|
|
$newMessage = new Message();
|
|
$newMessage->header->frame = MsgFrame::SYSTEM->value;
|
|
$newMessage->header->type = MsgType::HEARTBEAT->value;
|
|
$newMessage->header->to = Gateway::getUidByClientId($client_id);
|
|
Gateway::sendToClient($client_id, json_encode($newMessage));
|
|
}
|
|
|
|
/**
|
|
* 登录认证:校验 JWT,绑定 uid,更新在线状态
|
|
*/
|
|
private static function Auth($client_id, $header, $payload)
|
|
{
|
|
try {
|
|
$app = \addon\wxchat\worker\ChatEvent::initApp();
|
|
$token = \ywxapp\service\JwtService::instance()->parseAndValidate($payload->content ?? '');
|
|
$claims = $token->claims()->all();
|
|
$uid = (int)($claims['uid'] ?? 0);
|
|
if (! $uid) {
|
|
MsgReply::sendError($client_id, '认证失败:无效令牌');
|
|
Gateway::closeClient($client_id);
|
|
return;
|
|
}
|
|
|
|
$userLib = \ywxapp\library\Auth::instance();
|
|
$userLib->initUser($uid);
|
|
if (! $userLib->isLogin) {
|
|
MsgReply::sendError($client_id, '认证失败:用户不存在');
|
|
Gateway::closeClient($client_id);
|
|
return;
|
|
}
|
|
|
|
Gateway::bindUid($client_id, $uid);
|
|
|
|
// 更新在线状态
|
|
\ywxapp\model\MemberProfile::where('uid', $uid)
|
|
->update(['online_status' => 1, 'last_active_at' => time()]);
|
|
|
|
$newMsg = new Message();
|
|
$newMsg->header->frame = MsgFrame::SYSTEM->value;
|
|
$newMsg->header->type = MsgType::AUTH->value;
|
|
$newMsg->header->to = $uid;
|
|
$newMsg->payload->content = ['uid' => $uid, 'status' => 'success'];
|
|
Gateway::sendToClient($client_id, json_encode($newMsg));
|
|
|
|
// TODO: 拉取离线消息(从 DB history 由客户端主动拉取,此处可推送未读数)
|
|
} catch (\Throwable $th) {
|
|
echo "Auth failed: " . $th->getMessage() . "\n";
|
|
MsgReply::sendError($client_id, '认证失败:' . $th->getMessage());
|
|
Gateway::closeClient($client_id);
|
|
}
|
|
}
|
|
|
|
|
|
private static function Notification($client_id, $header, $payload)
|
|
{
|
|
// 服务端下发通知(如系统公告),当前仅回显
|
|
}
|
|
}
|