Reputation: 171
I am trying to build real time app using SSE. But it doesn't work when I think I write everything in right way. Please help me with this problem. I know websockets is better than SSE but I in beginning Here is my index.html code
<!DOCTYPE html>
<html>
<head>
<title>Using SSE(Server-sent event)</title>
<meta charset="utf-8">
</head>
<body>
<h1>Getting server updates</h1>
<div id="result"></div>
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("getdata.php");
source.onmessage = function(event) {
console.log(JSON.parse(event.data));
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>
and this is getdata.php page
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$pdo = new PDO("mysql:host=localhost;dbname=sse", 'root', 'secret');
$obj = $pdo->query("select * from users");
$arr = $obj->fetchAll();
echo "data: ".json_encode($arr);
flush();
?>
when i used
source.onerror = function(er){
console.log(er);
}
I got this
error { target: EventSource, isTrusted: true, currentTarget: EventSource, eventPhase: 2, bubbles: false, cancelable: false, defaultPrevented: false, composed: false, timeStamp: 5152.813223, cancelBubble: false, originalTarget: EventSource }
I tried comment code in html console.log(JSON.parse(event.data)); but it doesn't work too.
Please help understanding how SSE works and what is the wrong in my code?
Thanks in advance.
Upvotes: 3
Views: 1269
Reputation: 28913
Firstly, and most importantly, the PHP script should be running forever, not doing one query and then dying. (If that was your intention, then you don't need a streaming solution, and should just use AJAX.)
Second, you need two LFs after each data::
. And you (probably) also need ob_flush()
in addition to just flush()
. With all three changes it looks like this:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$pdo = new PDO("mysql:host=localhost;dbname=sse", 'root', 'secret');
while(true){ //Deliberate infinite loop
$obj = $pdo->query("select * from users");
$arr = $obj->fetchAll();
echo "data: ".json_encode($arr)."\n\n";
@ob_flush();@flush(); //Use @ to suppress v.rare but meaningless errors
sleep(1); //Poll the database every second.
}
?>
I've set it (the server) to poll the local database every second. You should adjust this based on the balance of server load against target latency.
IMPORTANT: This will send all user data to all clients, every second. You should redesign your SQL query to only fetch users that have changed since your last query. And then re-design the front-end to be given all users on the first call, and then after that just the changes.
Upvotes: 0
Reputation: 162
EDIT (just to leave in accordance for future viewers)
check (then press F12 in your browser and check "Console" - it's working for me in Firefox and Chrome)
See the code exactly as it are on that server:
sse.html
<!DOCTYPE html>
<html>
<head>
<title>Using SSE(Server-sent event)</title>
<meta charset="utf-8">
</head>
<body>
<h1>Getting server updates</h1>
<div id="result"></div>
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("getdata.php");
source.onmessage = function(event) {
console.log(JSON.parse(event.data));
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>
getdata.php (still mysql, not msqli or PDO because of an old server)
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
include("../../admin2/config.inc.php");
connect_db();
$query = mysql_query( "select * from ttbb" ) or die( mysql_error() );
$arr = mysql_fetch_object( $query );
echo "data: ".json_encode($arr)."\n\n";
flush();
?>
Upvotes: 1
Reputation: 171
I found out it why it doesn't work. I added \n\n
echo "data: ".json_encode($arr);
so it looks like this
echo "data: ".json.encode($arr)."\n\n";
I hope it helps
Upvotes: 3