Updating a webpage with server sent events in PHP - javascript

Hi I'm currently working on a personal project which has two components. I want to POST "baby, 1" to my server, and when my server receives that "baby, 1", I want to change the webpage to reflect the date (currently using the date to test). I'm currently using Postman to test and largely borrowing code from W3Schools.
testpage.php
<html lang ="en">
<head>
<meta charset ="UTF-8">
<title>Title</title>
</head>
<body>
<div id = "result"></div>
<script>
if (typeof(EventSource) !== "undefined")
{
var source = new EventSource("server.php");
document.getElementById("result").innerHTML+="thug";
source.onmessage = function (event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
}else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>
server.php
<?php
$bool = "";
if($_SERVER["REQUEST_METHOD"] == "POST") {
if (!empty($_POST["baby"])) {
$bool = $_POST["baby"];
if ($bool == 1) {
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
}
}
}
?>
When I test with the w3schools default code
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
?>
testpage.php updates properly. When I try to POST to server.php with (baby,1) testpage.php does not update. I am really struggling to figure out why this is happening.

Related

What determines how often a sever-sent-event is triggered

I am new to server-sent-events and copied the tutorial example from the w3 site.
The html page:
<html>
<body>
<div id="result"></div>
<script>
var source = new EventSource("sse.php");
source.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data + "<br>";
};
</script>
</body>
</html>
The php script:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
?>
This works and the page gets updated every 5 seconds.
My question is: Why 5 seconds? Is this a default setting for SSEs or is it something to do with the php date functionality or some php.ini setting?
EDIT
I change the php to this:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(true)
{
$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
sleep(1);
}
?>
and I get nothing, as if it is waiting for the php script to finish running (which it never will).
EDIT 2
PHP now changed to this (includes proper flush as suggested):
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while(true)
{
$time = date('r');
echo "data: The server time is: {$time}\n\n";
while (ob_get_level() > 0)
ob_end_flush();
flush();
if (connection_aborted())
break;
sleep(1);
}
?>
Still doing nothing.

How to use server sent event for control elements display for this case dom javascript?

How to use server sent event for control elements display for this case dom javascript ?
I tried to hide element on server sent event using dom but not work, how can i do ?
test.php
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript" src="1.8.3_test_jquery.minjs.js"></script>
<div id="result"></div>
<div id="hide_this_id">test</div>
<script>
if(typeof(EventSource) !== "undefined")
{
var source = new EventSource("test2.php");
source.onmessage = function(event){
document.getElementById("result").innerHTML += event.data +"<br>";
};
}
else
{
document.getElementById("result").innerHTML = "not support";
}
</script>
</body>
</html>
test2.php
<?php
include("connect.php");
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$loop = "1";
while($loop <= 1)
{
?>
<script>
document.getElementById("hide_this_id").style.display = "none";
</script>
<?PHP
ob_end_flush();
flush();
sleep(5); // wait for 5 seconds
}
?>

HTML5 Server-Sent Event

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.
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
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();
?>
print:
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.

Connecting to database via PHP and displaying contents on browser

I am connecting to an SQL server via PHP script and displaying the contents retrieved on the browser.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css"
href="http://cdn.sencha.com/ext/trial/5.0.0/build/packages/ext-theme-neptune/build/resources/ext-
theme-neptune-all.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/php" src="connection.php"></script>
</head>
<body>
</body>
</html>
app.js
document.addEventListener('DOMContentLoaded', function() {
d3.json("connection.php", function (data) {
document.write(data);
});
});
connection.php
<?php
// Server Name
$myServer = "10.112.1.2";
// Database
$connectionInfo = array("UID" => $uid, "PWD" => $pwd, "Database"=>"logs", "CharacterSet"=>"UTF-8");
$conn = sqlsrv_connect($myServer, $connectionInfo);
if (!$conn) {
$message = "Connection failed";
echo "<script type='text/javascript'>alert('$message');</script>";
} else {
$message = "Connected";
echo "<script type='text/javascript'>alert('$message');</script>";
}
$sql = "SELECT * FROM dbo.logsData";
$data = sqlsrv_query( $conn, $sql );
if( $data === false ) {
echo "Error in executing query.</br>";
die( print_r( sqlsrv_errors(), true));
}
$result = array();
do {
while ($row = sqlsrv_fetch_array($data, SQLSRV_FETCH_ASSOC)){
$result[] = $row;
}
} while ( sqlsrv_next_result($data) );
echo json_encode($result);
sqlsrv_free_stmt($data);
sqlsrv_close($conn);
?>
All 3 files are in the same folder.
The browser just displays a null and I don't hit any of the logging information from the .php file. Is my method right? Am I using the right javascript event?
Change your connection.php in this way:
if (!$conn) {
$message = "Connection failed";
echo "<script type='text/javascript'>alert('$message');</script>";
} else {
header('Content-Type: application/json');
}
You need to change mime type of your response. Moreover you cannot print out anything else than json data. That's way I removed from your code these lines:
$message = "Connected";
echo "<script type='text/javascript'>alert('$message');</script>";
Try using a relative pathname for connection.php here: d3.json("connection.php"
Something like "/dirname/connection.php".
You can test connection.php alone using a full pathname, like http://www.yourserver.xxx/dirname1/dirname2/...connection.php

Server Sent Events : Not working

I am using HTML5 Server-Sent Events.
Actually I need to show notification (new record enter and which are unread) that's when any new record is insert in database (php/mysql).
So for testing purpose I just tried with count of total row. But I am getting this error message in my local-host:
Firefox can't establish a connection to the server at http://localhost/project/folder/servevent/demo_sse.php.
The line is:
var source = new EventSource("demo_sse.php");
I have tried this:
index.php
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("demo_sse.php");
source.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>
<div id="result"></div>
demo_sse.php
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$db = mysql_connect("localhost", "root", ""); // your host, user, password
if(!$db) { echo mysql_error(); }
$select_db = mysql_select_db("testdatase"); // database name
if(!$select_db) { echo mysql_error(); }
$time = " SELECT count( id ) AS ct FROM `product` ";
$result = mysql_query($time);
$resa = mysql_fetch_assoc($result);
echo $resa['ct'];
flush();
?>
Please let me know what going wrong.
I know for notification we can use Ajax with some interval time, but I don't want such thing. As I have N number of records and which may slow my resources.
According to this,
There are several 'rules' that need to be met, and yours is lacking at this point:
Output the data to send (Always start with "data: ")
It is somehow like:
echo "data: {$resa['ct']}\n\n";
Setting a header to text/event-stream worked for me:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
// Rest of PHP code
Please modify the following code snippet according to your requirements
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
// infinite loop
while (1) {
// output the current timestamp; REPLACE WITH YOUR FUNCTIONALITY
$time = date('r');
echo "data: Server time: {$time}\n\n"; // 2 new line characters
ob_end_flush();
flush();
sleep(2); // wait for 2 seconds
}
?>
I tested this code snippet myself; it's working for me. If you have any query, let me know.

Categories

Resources