TheOrdinaryGeek
TheOrdinaryGeek

Reputation: 2323

Server Side Events Start/Stop

I am displaying some real time data from a MySQL database using PHP and JavaScript. Everything works as expected and the data is displaying as I want.

However, I would now like to implement two simple buttons to achieve the following;

I can get the stop button to work by using the EventSource close() function. I'm not so sure about how to resume from where I left off though. I think I may need to include the Last-Event-ID as described here.

My code so far is;

PHP

<?php 
session_start(); 
include 'conn.php'; // database connection
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Access-Control-Allow-Origin: *");

$query = "SELECT TimeStamp, CardNo, SerialNo FROM transactions ORDER BY TimeStamp DESC LIMIT 1";
$stmt = $conn->prepare($query);
$stmt->execute();
$result = $stmt->get_result();

if($row = $result->fetch_assoc()) {
    echo "retry: 100\n\n"; 
    if ($_SESSION["lastSerialNo"] != $row["SerialNo"]) {
        $_SESSION["lastSerialNo"] = $row["SerialNo"];
        echo "data: ".$row['SerialNo']. ' ' .$row['TimeStamp']. "\n\n";
        flush();
    }
    else {
        // do nothing
    }
}

JS & HTML

<script type="text/javascript">
    var source = new EventSource("data.php");
    window.onload = function() {
        source.onmessage = function(event){
            document.getElementById("result").innerHTML += "Data : " + event.data + "<br>";
        };
    };

    function stop() {
        source.close(); // this successfully stops the feed
        };

    function start() {
        // how to resume the feed?
        };  

    </script>

<button id="stop" onclick="stop()"> stop</button>
<button id="start" onclick="start()"> start</button>

Any help is appreciated.

Upvotes: 3

Views: 1063

Answers (1)

Andy
Andy

Reputation: 5395

When the PHP script returns data from the database, get it to return the ID (primary key) of the row it's sent back.

In Javascript you can write that to a hidden element each time you get a response.

When the user clicks "stop" it will stop updating that element, because nothing is being returned from the database.

When they click "start" read the element in the hidden div and add 1 to it (assuming the ID's are auto increment). Your next database query gets records from that point, etc.

Assume there's a hidden div with the ID #hiddenDiv

window.onload = function() {
    source.onmessage = function(event){
        // what you already had goes above
        document.getElementById("hiddenDiv").innerHTML = event.id;
    };
};

Each time you get data back from your PHP script it's writing event.id (the ID from the database) to the hidden div.

Then when they click "start" you read that value:

var lastRecord = document.getElementById("hiddenDiv").innerHTML;

And in your ajax request you would have to pass in lastRecord + 1 (you may need to cast that as an int, not sure exact syntax here).

Now in your query you SELECT records WHERE id = the ID you sent in the ajax request.

Your SQL query may need adjusting a bit because all it's doing at the moment is getting 1 record (the most recent one). If they press "stop" and there are say 13 more records to show, you'll have to handle that scenario. It may be possible to return all 13, or queue them, depending on what needs to be shown in the UI.

Another solution would be as described but use the TimeStamp field that you are already getting and write that to the div, instead of the row ID. Again, you adjust your SELECT query so it gets anything where TimeStamp > the timestamp from the hidden div.

Upvotes: 1

Related Questions