PHP , Using SSE, Can't echo the data back to JavaScript - javascript

So I am using SSE EventListener, Where this Script will Listen to OnMessage Event that happens at respond.php
if(typeof(EventSource !== "undefined")){
var source = new EventSource('respond.php');
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);}
else{
console.log("Sorry SSE is not working");
}
Respond.php
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
session_start();
if(isset($_POST['Body'])){
$myfile = fopen("data.txt","w");
$input = $_POST['Body'];
fwrite($myfile,"$input");
fclose($myfile);
echo "data: $input\n\n";
ob_flush();
flush();
}
This respond.php code basically say when this php gets an POST variable ready then write it to a data.txt then echo the data. I can see whenever I post an $_POST['Body'. data.txt gets update, So that means inside of the IF is getting executed BUT, the echo part just won't firing? The JAVASCRIPT onMessageListener is just not picking it up?(I did try to create an ELSE Part and echo something, and the Listener pick that up.)So I really don't know what is Happening here. Can someone please help?

Related

How to refresh the web page when index changes without lagging the server

I would like to refresh my static web page running on apache when the index changes. I've already tried to use server-side events, where I had a PHP file checking if the index changed and if yes, it sent the event to the webpage. This works exactly how I want, but there is a problem. Because the page is used by a lot of people sometimes (tens or up to a hundred opened tabs), it quickly starts to spam many apache processes. Then, it reaches the limit, and the apache freezes.
The question is how to handle this. If a user closes the tab, the process is killed, however, if not, the apache freezes.
The PHP script looks like this (it is checking two things, first, if the file chenged, or second if the status is something. As I said, this works fine, the problem is its lagging the server):
<?php
session_start();
session_write_close();
ignore_user_abort(false);
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$filename = "index.html";
while(True){
if ( connection_aborted() ){
exit();
}else{
try{
$string = file_get_contents("current_status.json");
$json = json_decode($string, true);
$pom1 = $json["state"];
$t1 = shell_exec("date -r index.html");
sleep(3);
$pom2 = $json["state"];
if($t1 != shell_exec("date -r index.html")) {
sleep(2);
echo "data: file changed \n\n";
} else if($pom2=="ready") {
sleep(2);
echo "data: new shot available \n\n";
} else {
echo "heartbeat";
}
ob_flush();
flush();
}
catch (\Error $e){
echo "data: error, json not available \n\n";
}
}
}
ob_end_flush()
?>
Then, there is a classical javascript function in the index file with event source on the PHP file.
My question is, how can I do this to not make apache crashing? Can I somehow set up SSE to handle it? I know I can allow more processes on apache, but my resources are limited.
Is there any other way how to do this? For example, live.js works as well, but the problem is the sam, a lot of processes when opened multiple times.
Yes, I can see how this would put far more strain on your server than necessary.
What you should do is poll for changes from javascript. You send an asynchronous request for the last time the index file changed from your javascript. You do it once when the page loads and store the time. Then you check again on an interval and compare the result with the first one. If it changed you refresh the page.
The PHP script should get the last change date, output it and exit - no continuously running PHP scripts.
Here is what the PHP file should look like:
<?php
header('Content-type: text/plain');
echo filemtime('index.html');
?>
Keep this minimal. The built in filemtime function is more efficient than running shell_exec commands.
Here is an example javascript:
chk_index_change_time(false);
function chk_index_change_time(last){
fetch('http://yourdomain.com/yourpath/get_index_change_time.php')
.then(res => res.text())
.then((index_change_time) => {
if ((false !== last) && (last != index_change_time)){
location.reload();
} else {
setTimeout(chk_index_change_time, 3000, index_change_time);
}
});
}
Feel free to error handling or whatever, but this will work. I used a timeout here instead of interval so that if the server is slow the server response time doesn't come out of the 3 second delay.

how can I use curl with javascript

i am using curl to open a page and want to play video using javascript that was shown on the page . i have used following code
$url = "https://www.example.com/";
$link = "http://www.example.com/oembed?url=" . $url. "&format=json";
$curl = curl_init($link);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($curl);
curl_close($curl);
$result = json_decode($return, true);
echo '<pre>'; print_r($result);
echo $result['html'];
play();
function play(){
document.getElementById("play-button").click();
}
my curl is working but it didn't play the video.where am iI wrong? do i have pass the x-path of the button to play video?
PHP scripts are executed on the server, while JavaScript is executed on the browser (Node.js is an exception). Thus your PHP code is already executed when the JS wanted to call the click action and there's no way that the PHP code will execute on the browser, thus the curl is not getting called.
What you need to do is call the URL using JavaScript asynchronously. You can either use Ajax or Fetch for this.

How can i access javascript variable in kirby cms for “limit” functionality

Just like in demo of kirby
<?php foreach(page('projects')->children()->visible()->limit(3) as $project): ?>
I want to make dynamic limit of records.
How can i do that?
I have tried JavaScript but it not worked.
Here is JavaScript code that no worked
<script>
var p1 = 3;
function load()
{
p1=p1+3;
}
</script>
<?php
$number="<script>document.write(p1)</script>";
// echo $number;
<?php foreach(page('projects')->children()->visible()->limit($number) as $project): ?>
//Code Here
<?php endforeach ?>
<div class="text-center">LOAD MORE</div>
suggest me if anyone has done it.
You can't, at least not in this way.
Think of when and where your code is getting executed. PHP is executed by the server, before the browser even receives the page. JavaScript is executed by the browser, after the page is done loading.
You can either have a separate script that generates what you need from your number, and pass that as a GET or POST value to the script via an AJAX request, or generate the number you need in PHP.
So in case of an AJAX request you'd have your PHP script doing something like:
<?php
$number = $_GET['number'];
foreach (page('projects')->children()->visible()->limit($number) as $project) {
echo .....
}
?>
and your JavaScript would call that script via an AJAX request and put the resulting HTML into your page, with something like:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
document.getElementById("container").innerHTML = xht.responseText;
}
xhr.open("GET", "script.php?number=" + p1, true);
xhr.send();

simple server sent-event: clock stop after 30 minutes

I would make a simple clock with sent-event my code is:
The client and server is on LAN, and the browser is iceweasel v.38.7.1.
php:
<?php
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");
function sendMsg($msg) {
echo "retry: 1000\n";
echo "data: $msg" .PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
sendMsg(date("H:i", time()));
js
(function get_time()
{var source = new EventSource('/config/rtc/get_time.php');
source.addEventListener('message',function (event)
{document.getElementById("orologio").innerHTML=event.data;},false);
source.addEventListener('error', function(event) {
if (event.readyState === EventSource.CLOSED)
{get_time();}},false);
})();
The clock work for 30-45 minutes, after it stop,
Where I did go wrong?
thanks.
Your PHP script should look like:
<?php
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");
function sendMsg($msg) {
echo "retry: 1000\n";
echo "data: $msg" .PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
while(true){
sendMsg(date("H:i", time()));
sleep(1);
}
Otherwise your PHP script is constantly closing (which totally does away with the point of using SSE), the SSE socket closes, and the browser then auto-reconnects. Theoretically ad infinitum, but possibly something gets fed up after 30 minutes :-)
What I thought the problem was going to be was script time-out. So at the top of your PHP script you should add:
set_time_limit(0);
Again, this is saying you want the PHP script to run forever, that the infinite loop is by design, and not a mistake.

Detecting user abort/navigation websockets

I'm experimenting with websockets and would like to detect if a user has navigated away from the page to the PHP stream script from running. Everything else is working fine.
Everything I try to do does not stop the PHP script from running (using Xampp locally).
I'm currently working with javascript's beforeunload, and PHP's connection_aborted(), connection_status() and even file_exists() (which is the only one that works currently!!!).
Until the script exists or I restart apache I cannot reload the page but it's the abort detection that I have to get working. Firebug reports the socket script has aborted but PHP just keeps ion running. Any help appreciated.
My javascript looks like this
function socket_open(){
if(!!window.EventSource){
var websocket = new EventSource('./ajax/progress.php');
websocket.addEventListener('message', function(e){
var data = JSON.parse(e.data);
console.log(data);
},false);
$(window).bind('beforeunload', function(){
websocket.onclose = function(){};
websocket.close();
});
}
}
And my PHP is like this.
./ajax/progress.php
function get_task_progress(){
$output = array();
//conditionally create some output
if(!empty($output)){
echo 'data: '.json_encode($output)."\n\n";
ob_flush();
flush();
}
sleep(1);
if(!connection_aborted() && connection_status()==0 && file_exists('1.txt')){
get_task_progress();
}
}
I seem to have solved it but echoing and flushing a no updates status on every request before the test for a live connection
if(!empty($output)){
$tasks_state = $tasks_new;
echo 'data: '.json_encode($output)."\n\n";
}else{
echo 'data: '.json_encode(array('e'=>0))."\n\n";
}
ob_flush();
flush();
sleep(1);
if(!connection_aborted() && connection_status()==0){
get_task_progress();
}

Categories