type); Cache::put(\App\Utils\CacheKey::get('SERVER_' . $nodeType . '_LAST_CHECK_AT', $nodeId), time(), 3600); ServerService::updateMetrics($node, $data); Log::debug("[WS] Node#{$nodeId} status updated"); } /** * Handle device report from node * * 数据格式: {"event": "report.devices", "data": {userId: [ip1, ip2, ...], ...}} */ public static function handleDeviceReport(TcpConnection $conn, int $nodeId, array $data): void { $service = app(DeviceStateService::class); // Get old data $oldDevices = $service->getNodeDevices($nodeId); // Calculate diff $removedUsers = array_diff_key($oldDevices, $data); $newDevices = []; foreach ($data as $userId => $ips) { if (is_numeric($userId) && is_array($ips)) { $newDevices[(int) $userId] = $ips; } } // Handle removed users foreach ($removedUsers as $userId => $ips) { $service->removeNodeDevices($nodeId, $userId); $service->notifyUpdate($userId); } // Handle new/updated users foreach ($newDevices as $userId => $ips) { $service->setDevices($userId, $nodeId, $ips); } // Mark for push Redis::sadd('device:push_pending_nodes', $nodeId); Log::debug("[WS] Node#{$nodeId} synced " . count($newDevices) . " users, removed " . count($removedUsers)); } /** * Handle device state request from node */ public static function handleDeviceRequest(TcpConnection $conn, int $nodeId, array $data = []): void { $node = Server::find($nodeId); if (!$node) return; $users = ServerService::getAvailableUsers($node); $userIds = $users->pluck('id')->toArray(); $service = app(DeviceStateService::class); $devices = $service->getUsersDevices($userIds); $conn->send(json_encode([ 'event' => 'sync.devices', 'data' => ['users' => $devices], ])); Log::debug("[WS] Node#{$nodeId} requested devices, sent " . count($devices) . " users"); } /** * Push device state to node */ public static function pushDeviceStateToNode(int $nodeId, DeviceStateService $service): void { $node = Server::find($nodeId); if (!$node) return; $users = ServerService::getAvailableUsers($node); $userIds = $users->pluck('id')->toArray(); $devices = $service->getUsersDevices($userIds); NodeRegistry::send($nodeId, 'sync.devices', [ 'users' => $devices ]); Log::debug("[WS] Pushed device state to node#{$nodeId}: " . count($devices) . " users"); } /** * Push full config + users to newly connected node */ public static function pushFullSync(TcpConnection $conn, Server $node): void { $nodeId = $conn->nodeId; // Push config $config = ServerService::buildNodeConfig($node); $conn->send(json_encode([ 'event' => 'sync.config', 'data' => ['config' => $config] ])); // Push users $users = ServerService::getAvailableUsers($node)->toArray(); $conn->send(json_encode([ 'event' => 'sync.users', 'data' => ['users' => $users] ])); Log::info("[WS] Full sync pushed to node#{$nodeId}", [ 'users' => count($users), ]); } }