Commit
This commit is contained in:
parent
ecded9573d
commit
63ac3c49e1
35
app/lib/App/SSE/Sender.php
Normal file
35
app/lib/App/SSE/Sender.php
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +1,10 @@
|
|||||||
<h1>Live resultater</h1>
|
<h1>Live resultater</h1>
|
||||||
<p id="response">Venter på data...</p>
|
<p id="response">Venter på data...</p>
|
||||||
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
|
|
||||||
<script>
|
<script>
|
||||||
function getContent(timestamp)
|
var source = new EventSource('stream.php');
|
||||||
{
|
|
||||||
var queryString = {'timestamp' : timestamp};
|
|
||||||
|
|
||||||
$.ajax(
|
source.addEventListener('message', function(e) {
|
||||||
{
|
console.log(e.data);
|
||||||
type: 'GET',
|
}, false);
|
||||||
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();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
@ -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
30
public/race/stream.php
Normal 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);
|
||||||
|
}
|
Reference in New Issue
Block a user