This commit is contained in:
William 2022-03-23 10:08:36 +01:00
parent ecded9573d
commit 63ac3c49e1
4 changed files with 70 additions and 63 deletions

View File

@ -0,0 +1,35 @@
<?php
namespace App\SSE;
/**
* Small class to abstract Server-Sent Events (SSE)
*
* https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
*/
class Sender
{
public function __construct()
{
header("Cache-Control: no-store");
header("Content-Type: text/event-stream");
// as session data is locked to prevent concurrent writes we
// make it read only to prevent the server from locking up
session_write_close();
}
public function send($data, $event = NULL): void
{
if ($event)
{
echo "event: $event\n";
}
echo "data: " . json_encode($data) ."";
echo "\n\n";
// send data to stream
ob_end_flush();
flush();
}
}

View File

@ -1,30 +1,10 @@
<h1>Live resultater</h1>
<p id="response">Venter data...</p>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script>
function getContent(timestamp)
{
var queryString = {'timestamp' : timestamp};
var source = new EventSource('stream.php');
$.ajax(
{
type: 'GET',
url: 'long-polling.php',
data: queryString,
success: function(data){
// put result data into "obj"
var obj = jQuery.parseJSON(data);
// put the data_from_file into #response
$('#response').html(obj.data);
// call the function again, this time with the timestamp we just got from server.php
getContent(obj.timestamp);
}
}
);
}
// initialize jQuery
$(function() {
getContent();
});
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
</script>

View File

@ -1,38 +0,0 @@
<?php $app = require '../../app/inc.php';
use App\Timetable\TimeMapper;
$timeMapper = new TimeMapper($app->database->conn);
/**
* Long polling
*/
session_write_close();
ignore_user_abort(false);
set_time_limit(30);
// if ajax request has send a timestamp, then $last_ajax_call = timestamp, else $last_ajax_call = null
$last_ajax_call = isset($_GET['timestamp']) ? (int)$_GET['timestamp'] : NULL;
// main loop
while(TRUE)
{
$time = $timeMapper->getLatest();
if ($time)
{
$last_change_in_timetable = $time->date->getTimestamp();
if ($time && $last_ajax_call == NULL || $last_change_in_timetable > $last_ajax_call)
{
exit(json_encode(["data" => json_encode($timeMapper->getAll()), "timestamp" => $last_change_in_timetable]));
}
}
// PHP caches file data, like requesting the size of a file, by default. clearstatcache() clears that cache
clearstatcache();
// wait for 1 sec (not very sexy as this blocks the PHP/Apache process, but that's how it goes)
sleep(1);
continue;
}

30
public/race/stream.php Normal file
View File

@ -0,0 +1,30 @@
<?php $app = require '../../app/inc.php';
use App\Timetable\TimeMapper;
use App\SSE\Sender;
$timeMapper = new TimeMapper($app->database->conn);
/**
* Server-Sent Events (SSE)
*/
$sse = new Sender();
$last_change_in_timetable;
while (!connection_aborted())
{
$time = $timeMapper->getLatest();
if ($time)
{
$last_change_in_timetable = $time->date->getTimestamp();
if ($last_time == NULL || $last_change_in_timetable > $last_ajax_call)
{
$sse->send($timeMapper->getAll());
}
}
sleep(1);
}