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.
Related
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.
I have a simple AJAX function bound to a button that should execute a PostgreSQL query. However, when I click the button that I bound the ajax query to, all I get is the confirmation that the database connection was successful. Nothing seems to happen withe the ajax result (should be printing to console in the handleAjax() function. What am I doing wrong?
This is the javascript code (with jquery):
$(document).ready(function() {
function sendAjax() {
$.ajax({
url: "db/database.php",
success: function (result) {
handleAjax(result);
}
});
}
function handleAjax(result) {
console.log(result);
}
$("#submit-button").on("click", sendAjax);
});
And this it the contents of database.php:
<?php
function dbconn(){
ini_set('display_errors', 1); // Displays errors
//database login info
$host = 'localhost';
$port = 5432;
$dbname = 'sms';
$user = 'postgres';
$password = 'postgres';
// establish connection
$conn = pg_connect("host=$host port=$port dbname=$dbname user=$user password=$password");
if (!$conn) {
echo "Not connected : " . pg_error();
exit;
} else {
echo "Connected.";
}
}
$conn = dbconn();
$sql = "SELECT * FROM numbers;";
$result = pg_query( $sql ) or die('Query Failed: ' .pg_last_error());
$count = 0;
$text = 'error';
while( $row = pg_fetch_array( $result, null, PGSQL_ASSOC ) ) {
$text = $row['message'];
//echo $text;
}
pg_free_result( $result );
?>
The problem is in the database.php file, all you get is "Connected." because you don't print your result at the end. Ajax only receive the output of the php file.
So at the end of your php file you should add :
echo $text;
And you also should remove the echo "Connected.";
AJAX is not a magic wand that in magic way reads PHP code. Let's say AJAX is a user. So what does user do.
Open web page
Wait until PHP execute code and display data
Tells you what he sees
If you don't display anything, ajax can't tell you what he saw.
In thi's place is worth to say that the best way to communicate between PHP and AJAX is using JSON format.
Your code generally is good. All you have to do is to display your data. All your data is in your $text var. So let's convert your array ($text) to JSON.
header('Content-Type: application/json');
echo json_encode($text);
First you set content-type to json, so ajax knows that he reads json. Then you encode (convert) your PHP array to js-friendly format (JSON). Also delete unnecessary echoes like 'Conntected' because as I said, AJAX reads everything what he sees.
You should return $conn from dbconn()
if (!$conn) {
echo "Not connected : " . pg_error();
exit;
} else {
echo "Connected.";
return $conn;
}
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.
I coded a website using HTML5 Server Sent Events and it's working like charm on Godaddy shared hosting, however the same site with exactly the same code isn't working on 101domain shared hosting.
Rest all is working fine, except chat functionality using Server Sent Events.
How to find the errors in the script.
Here is the HTML page, with SSE javascript code.
<?php
$get_value_this_url = "globalchat";
?>
<div id="chat">
<div id="chats-div">
<p id="tip">(tip! kickstart a discussion by sharing this page)</p>
<ul id="chats-ul">
<?php
/*This session id will be used to fetch the latest chat via SSE*/
$_SESSION["id"] = 1;
if($stmt = $con->prepare("SELECT `icicinbbcts_id`, `icicinbbcts_user`, `icicinbbcts_chats` FROM `icicinbbcts_chats` WHERE `icicinbbcts_video_id` = ? ORDER BY `icicinbbcts_id` DESC LIMIT 25")){
$stmt->bind_param("s", $video_id);
$video_id = $get_value_this_url;
if ($stmt->execute()) {
$stmt->bind_result($id, $user, $chats);
$stmt->store_result();
if($stmt->num_rows() > 0){
$_SESSION["offset"] = $stmt->num_rows;
}
while ($stmt->fetch()) {
//print_r($user .": ". $chats."<br>");
echo '<li class="chats"><span id="nicknameChats">'.$user.'</span>: '.$chats.'</li>';
//echo '<span class="line-spacing"></span>';
$_SESSION["offset"] = $stmt->num_rows;
if($_SESSION["id"] < $id){
$_SESSION["id"] = $id;
}
}
}else
echo $stmt->error;
}else
echo $stmt->error;
$stmt->free_result();
$stmt->close();
?>
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("auto_update.php?r=<?php echo $get_value_this_url; ?>");
source.onmessage = function(event) {
var obj = JSON.parse(event.data);
$("#chats-ul").append('<li class="chats"><span id="nicknameChats">'+obj.user+'</span>: '+obj.chats+'</li>');
$('#chats-ul').scrollTop($(window).height());
};
} else {
document.getElementById("chats-ul").innerHTML = "Your browser doesn't support a part of HTML5, so please use modern browsers like Chrome, Firefox, etc.";
}
</script>
</ul>
</div>
<input id="text-area" class="q" name="text-input" form="textForm" maxlength="140" placeholder="Type to comment" ></input>
</div>
And here's the server side PHP script.
<?php session_start(); ?>
<?php //error_reporting(E_ALL); ?>
<?php require "connection.php";?>
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
if($stmt = $con->prepare("SELECT `icicinbbcts_id`, `icicinbbcts_user`, `icicinbbcts_chats` FROM `icicinbbcts_chats` WHERE `icicinbbcts_video_id` = ? AND `icicinbbcts_id` > ? ORDER BY `icicinbbcts_id` DESC")){
$stmt->bind_param("si", $video_id, $row_id);
$row_id = $_SESSION["id"];
$video_id = mysqli_real_escape_string($con, strip_tags($_GET["r"]));
if ($stmt->execute()) {
$stmt->bind_result($id, $user, $chats);
$stmt->store_result();
if($stmt->num_rows > 0){
while ($row = $stmt->fetch()) {
if($_SESSION["id"] < $id){
$send = array("user" => $user, "chats" => $chats);
echo "retry: 100\n";
echo "data: ".json_encode($send)."\n\n";
ob_end_flush();
flush();
$_SESSION["id"] = $id;
}
}
}
}else
echo $stmt->error;
}else
echo $stmt->error;
$stmt->close();
?>
The same above code works perfectly on Godaddy shared hosting, however the save code just isn't working on 101domain.
I tried putting charset UTF-8 in both PHP and HTML, but that din't help, I tried adding ob_flush in server side PHP script and it din't help too.
There's nothing wrong with connection.php because same file on other pages works fine.
On chat functionality the chat messages are getting inserted into the database, however it's not showing on the page, unless we refresh the page.
How to check for errors and how to debug Server Sent Events?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
I did console.log and didn't find the log in chrome, when I placed console.log code at the point shown below in the code.
<script>
if(typeof(EventSource) !== "undefined") {
console.log("SSE is supported"); //placing console.log here, displays the message in chrome developer tool
var source = new EventSource("auto_update.php?r=<?php echo $get_value_this_url; ?>");
source.onmessage = function(event) {
console.log("message isn't received from server"); //placing console.log here doesn't display any log message in Chrome Developer Tool
var obj = JSON.parse(event.data);
$("#chats-ul").append('<li class="chats"><span id="nicknameChats">'+obj.user+'</span>: '+obj.chats+'</li>');
$('#chats-ul').scrollTop($(window).height());
};
} else {
document.getElementById("chats-ul").innerHTML = "Your browser doesn't support a part of HTML5, so please use modern browsers like Chrome, Firefox, etc.";
}
</script>
So from the console.log above, we see that the SSE script is not receiving messages from backend, and backend code is shown above, can you show what's wrong with the backend code?
Since the result it works with one provider but not another, it is probably a server configuration issue.
Here are some things you can try to narrow down the issue:
In the javascript script use console.log(event) to check if you are getting anything from the server
Check the network tab in the developer tools area of browsers (in Chrome choose other to view server sent events).
If there is no output then try narrowing the problem down on the server. Resolev SSE output early to see if SSE mechanism works. Bit by bit resolve the SSE later and later until it breaks. If there is a difference on a specific line between providers it may be due to the PHP version. To compare php versions run <?php phpinfo() ? in a php file.
If you find a difference contact your provider!
You want to report errors?
<?php
// Turn off error reporting
error_reporting(0);
// Report runtime errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);
// Report all errors
error_reporting(E_ALL);
// Same as error_reporting(E_ALL);
ini_set("error_reporting", E_ALL);
// Report all errors except E_NOTICE
error_reporting(E_ALL & ~E_NOTICE);
?>
I am trying to generate a file to download. With JavaScript I call a PHP file to process my request and send back the result in a way it should be possible to download it. But instead of making it available for download it simply display the code.
PHP
function export()
{
// Get a database object.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select fields to get.
$fields = array(
$db->quoteName('params')
);
// Conditions for which records should be get.
$conditions = array(
$db->quoteName('element') . ' = ' . $db->quote('plugin_name'),
$db->quoteName('folder') . ' = ' . $db->quote('system')
);
// Set the query and load the result.
$query->select($fields)->from($db->quoteName('#__extensions'))->where($conditions);
$db->setQuery($query);
$results = $db->loadResult();
// Namming the filename that will be generated.
$name = 'file_name';
$date = date("Ymd");
$json_name = $name."-".$date;
// Clean the output buffer.
ob_clean();
echo $results;
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
}
JavaScript
function downloadFile() {
var fd = new FormData();
fd.append('task', 'export');
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", uploadComplete, false);
xhr.open("POST", "my_php_file");
xhr.send(fd);
}
HTML file
<button class="btn btn-primary btn-success" type="button" onclick="downloadFile()"></button>
UPDATE MY CODE
You need to call any header function calls before you output data. Otherwise you will get a headers "Headers already sent" warning, and the headers will not be set.
Example:
...
// Namming the filename that will be generated.
$name = 'file_name';
$date = date("Ymd");
$json_name = $name."-".$date;
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
// Clean the output buffer.
ob_clean();
echo $results;
An example
<?php
ob_start();
echo "some content to go in a file";
$contentToGoInFile = ob_get_contents(); //this gets the outputted content above and puts it into a varible/buffer
ob_end_clean();
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
echo $contentToGoInFile;
exit; //stops execution of code below
example with your code
$results = $db->loadResult();
// Namming the filename that will be generated.
$name = 'file_name';
$date = date("Ymd");
$json_name = $name."-".$date;
ob_start();
echo $results;
$contentToGoInFile = ob_get_contents(); //this gets the outputted content above and puts it into a varible/buffer
ob_end_clean();
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
echo $contentToGoInFile;
exit