From ad754a704eba58394bffb593d94e5027c241dc14 Mon Sep 17 00:00:00 2001 From: lkddi Date: Tue, 17 Mar 2026 20:54:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=88=BF=E9=97=B4=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=9C=A8=E7=BA=BF=E4=BA=BA=E6=95=B0=E4=B8=8D=E5=87=86?= =?UTF-8?q?=EF=BC=9A=E6=88=BF=E9=97=B4Tab=E6=AF=8F30=E7=A7=92=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=88=B7=E6=96=B0+=E6=87=92=E6=B8=85=E7=90=86?= =?UTF-8?q?=E6=8E=89=E7=BA=BF=E5=83=B5=E5=B0=B8=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Services/ChatStateService.php | 22 +++++++++++++++++++ .../views/chat/partials/scripts.blade.php | 9 +++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/Services/ChatStateService.php b/app/Services/ChatStateService.php index 7f73239..de3f68d 100644 --- a/app/Services/ChatStateService.php +++ b/app/Services/ChatStateService.php @@ -28,6 +28,8 @@ class ChatStateService { $key = "room:{$roomId}:users"; Redis::hset($key, $username, json_encode($info, JSON_UNESCAPED_UNICODE)); + // 写入活跃标记(90秒 TTL,心跳每次刷新;超出则被认定为掉线) + Redis::setex("room:{$roomId}:alive:{$username}", 90, 1); } /** @@ -40,6 +42,19 @@ class ChatStateService { $key = "room:{$roomId}:users"; Redis::hdel($key, $username); + // 同时删除活跃标记 + Redis::del("room:{$roomId}:alive:{$username}"); + } + + /** + * 刷新用户心跳活跃标记(心跳接口调用)。 + * + * @param int $roomId 房间ID + * @param string $username 用户名 + */ + public function refreshAlive(int $roomId, string $username): void + { + Redis::setex("room:{$roomId}:alive:{$username}", 90, 1); } /** @@ -85,6 +100,13 @@ class ChatStateService $result = []; foreach ($users as $username => $jsonInfo) { + // 过滤掌心跳已超出活跃窗口的用户(掉线超 90秒) + if (! Redis::exists("room:{$roomId}:alive:{$username}")) { + // 懒清理:顺手将僵尸记录从 hash 中移除 + Redis::hdel($key, $username); + + continue; + } $result[$username] = json_decode($jsonInfo, true); } diff --git a/resources/views/chat/partials/scripts.blade.php b/resources/views/chat/partials/scripts.blade.php index b931cca..ced62d4 100644 --- a/resources/views/chat/partials/scripts.blade.php +++ b/resources/views/chat/partials/scripts.blade.php @@ -42,15 +42,22 @@ let _maxMsgId = 0; // 记录当前收到的最大消息 ID // ── Tab 切换 ────────────────────────────────────── + let _roomsRefreshTimer = null; + function switchTab(tab) { // 切换名单/房间 面板 ['users', 'rooms'].forEach(t => { document.getElementById('panel-' + t).style.display = t === tab ? 'block' : 'none'; document.getElementById('tab-' + t)?.classList.toggle('active', t === tab); }); - // 房间 Tab:拉取在线人数列表 + // 房间 Tab:立即拉取 + 每 30 秒自动刷新在线人数 if (tab === 'rooms') { loadRoomsOnlineStatus(); + clearInterval(_roomsRefreshTimer); + _roomsRefreshTimer = setInterval(loadRoomsOnlineStatus, 30000); + } else { + clearInterval(_roomsRefreshTimer); + _roomsRefreshTimer = null; } }