getHeaderLine('Upgrade') === 'websocket') { $connection = new WebSocketConnection(); $connections[] = $connection; // Send initial data $connection->send(json_encode([ 'type' => 'welcome', 'message' => 'Connected to real-time data stream' ])); return $connection; } return new React\Http\Response(404, [], 'WebSocket endpoint only'); }); // Periodic data broadcast $loop->addPeriodicTimer(1.0, function() use (&$connections, $pdo) { if (empty($connections)) return; try { // Get latest data for all active tags $stmt = $pdo->prepare(" SELECT h.TimeStamp, h.Value, n.name FROM historicaldata h LEFT JOIN id_names n ON h.ID = n.idnumber WHERE h.TimeStamp >= NOW() - INTERVAL 5 SECOND ORDER BY h.TimeStamp DESC "); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if (!empty($data)) { $message = json_encode([ 'type' => 'data_update', 'timestamp' => date('c'), 'data' => $data ]); // Broadcast to all connections foreach ($connections as $key => $connection) { if ($connection->isConnected()) { $connection->send($message); } else { unset($connections[$key]); } } } } catch (Exception $e) { error_log("WebSocket error: " . $e->getMessage()); } }); $socket = new Server('0.0.0.0:8080', $loop); $server->listen($socket); echo "WebSocket server running on port 8080\n"; $loop->run(); ?>