From eb7bc58417e4a1f6a7beb40ae4e654d3dd749eb1 Mon Sep 17 00:00:00 2001 From: lkddi Date: Fri, 27 Feb 2026 12:48:23 +0800 Subject: [PATCH] =?UTF-8?q?Fix:=20=E5=BD=BB=E5=BA=95=E6=8A=9B=E5=BC=83Redi?= =?UTF-8?q?s=20SCAN=E6=96=B9=E6=A1=88=EF=BC=8C=E6=94=B9=E7=94=A8Room::pluc?= =?UTF-8?q?k+hkeys=E7=B2=BE=E5=87=86=E8=AF=BB=E5=8F=96=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E7=94=A8=E6=88=B7=EF=BC=8C=E8=A7=A3=E5=86=B3predis=E5=89=8D?= =?UTF-8?q?=E7=BC=80=E5=AF=BC=E8=87=B4=E6=89=AB=E6=8F=8F=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Commands/AutoSaveExp.php | 30 ++++++++++++---------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/app/Console/Commands/AutoSaveExp.php b/app/Console/Commands/AutoSaveExp.php index 07fa3f5..258431f 100644 --- a/app/Console/Commands/AutoSaveExp.php +++ b/app/Console/Commands/AutoSaveExp.php @@ -87,32 +87,28 @@ class AutoSaveExp extends Command } /** - * 扫描 Redis,获取所有活跃房间及其在线用户列表。 + * 查询所有活跃房间及其在线用户列表。 + * + * 改为从数据库获取所有房间,再用 Redis::hkeys() 查询在线用户。 + * 这样可以避免 Redis SCAN + 前缀匹配不一致的问题, + * 且 Redis::hkeys() 会自动正确地加上前缀,与 ChatStateService::userJoin() 一致。 * * @return array> 格式:[房间ID => [用户名, ...]] */ private function scanOnlineRooms(): array { $roomMap = []; - $cursor = '0'; - // 获取原始 Redis 客户端(不自动加前缀),用于直接操作完整 key 名 - $rawClient = Redis::connection()->client(); + // 从数据库取出所有房间 ID + $roomIds = \App\Models\Room::pluck('id'); - do { - [$cursor, $keys] = Redis::scan($cursor, ['match' => '*room:*:users', 'count' => 100]); - foreach ($keys ?? [] as $key) { - // 从 key 中提取房间 ID,支持带前缀的格式(如 chatroom-database-room:1:users) - if (preg_match('/room:(\d+):users/', $key, $m)) { - $roomId = (int) $m[1]; - // 直接用原始客户端查找,避免 Laravel 自动加前缀导致 key 被拼接两次 - $usernames = $rawClient->hkeys($key); - if (! empty($usernames)) { - $roomMap[$roomId] = $usernames; - } - } + foreach ($roomIds as $roomId) { + // Laravel 的 Redis facade 会自动加配置的前缀,与 ChatStateService 存入时完全一致 + $usernames = Redis::hkeys("room:{$roomId}:users"); + if (! empty($usernames)) { + $roomMap[(int) $roomId] = $usernames; } - } while ($cursor !== '0'); + } return $roomMap; }