// +---------------------------------------------------------------------- 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 */ 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) { // 服务端下发通知(如系统公告),当前仅回显 } }