Files
controls-web/trends/live/websocket_server.php
2026-02-17 12:44:37 -06:00

78 lines
2.2 KiB
PHP

<?php
require_once 'vendor/autoload.php'; // Install ReactPHP via Composer
use React\Socket\Server;
use React\Http\Server as HttpServer;
use React\Stream\WritableResourceStream;
$loop = React\EventLoop\Loop::get();
// Database connection
$pdo = new PDO("mysql:host=192.168.0.13;dbname=history", "opce", "opcelasuca");
// WebSocket connections
$connections = [];
// Create WebSocket server
$server = new HttpServer($loop, function ($request) use (&$connections, $pdo) {
// Handle WebSocket upgrade
if ($request->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();
?>