Dynamic page refresh JavaScript/PHP or 'Pusher.com' - javascript

I'm looking for a solution to be able to dynamically force a refresh on my web page to all my current viewers. It would be easiest if this was done through php however I'm open to suggestions.
I have done some research and have found a possible solution (pusher.com) however I'm not sure how to execute this. Here is my code below:
JavaScript on my web page added to document.ready jQuery':
var pusher = new Pusher('xxx');
var refreshChannel = pusher.subscribe('refreshing');
refreshChannel.bind('refresh-event', function() {
location.reload(true);
});
Here is my php code from their official documentation:
<?php
require('Pusher.php');
$options = array(
'cluster' => 'eu',
'encrypted' => true
);
$pusher = new Pusher(
'xxx',
'xxx',
'xxx',
$options);
$data['message'] = 'hello world';
$pusher->trigger('refresh-event', 'refresh', $data);
?>
I understand how to send a message like shown above but I don't know how to enable the refresh code. Has anyone used this sdk before and knows how?
Alternatively
Would anyone know any libraries or solutions on how to accomplish this task? Again, all I'm looking to do is refresh my web page dynamically to all my current viewers as and when I need to do it.

You callback function which is the second parameter to refreshChannel.bind(...) will run whenever a 'refresh-event' is received on channel 'refreshing'. The $data in your PHP gets passed to that function as well so you can send information with the event.
Your code to do this is almost spot on but it looks like you are forgetting to set the cluster in your javascript, so aren't successfully connecting. If your app is on the 'eu' cluster you need to say so when you try to connect:
var pusher = new Pusher('xxx', {
cluster: 'eu',
encrypted: true
});
You should have been getting "Could not find app by key xxx. Perhaps you're connecting to the wrong cluster." errors in the javascript console when you try to load the page.
edit: also on closer inspection your channel name and event are the wrong way around in your trigger call. It's
$pusher->trigger('channel-name', 'event', $data);
edit 2: also in your javascript you're calling the channel 'refreshing' and in your php you're calling it 'refresh'. These have to be the same.

Your clients (pages that have the JavaScript code) make a WebSocket connection with pusher.com. You must trigger (= post data) to pusher api server via your php script and pusher will forward your data (event name + parameters) to all clients (connected sockets).
If you have your php code for example in index.php and access it via http it will send data to pusher and he will inform your clients.
Alternative to pusher.com you can create your own php WebSocket server.
Libs:
socketo.me and
socket.io

Related

Using EventSource with Ajax

I am trying to work out how EventSource might help solve an update problem with a web applications.
I would like to be able to notify visitors to a web page when one or another visitor has performed an update. The idea is:
One visitor makes some changes to a text area and submits.
The data is submitted using Ajax.
At the server, the changes are saved.
I would like the server to send a notification that changes have been made
I would like all other visitors to get this notification.
On the server in PHP, I have something like this:
if(isset($_POST['save'])) {
// process changes
$data = sprintf('data: {"time": "%s","type": "save"}',$date);
header("Cache-Control: no-store");
header("Content-Type: text/event-stream");
print "event: ping\n$data\n\n";
ob_flush();
flush();
exit;
}
In JavaScript I have something like this:
var eventSource = new EventSource("https://example.net/ajax.php", { withCredentials: true } );
eventSource.addEventListener("ping", (event) => {
const time = JSON.parse(event.data).time;
const type = JSON.parse(event.data).type;
console.log(`Ping at ${time} for ${type}`);
});
That doesn’t do the job at all. At the client end I get get an error message about the wrong headers (I think that it’s because there’s no save yet, so the PHP falls through to an empty string).
All the samples I have seen include a while(true) loop in the PHP, but non have a one-off event.
Is this possible to implement, and, if so, how?

Add Variable to PHP Session Array From Dynamically created HTML element within PHP Echo [duplicate]

Is it possible to set PHP session variables using Javascript?
In JavaScript:
jQuery('#div_session_write').load('session_write.php?session_name=new_value');
In session_write.php file:
<?
session_start();
if (isset($_GET['session_name'])) {$_SESSION['session_name'] = $_GET['session_name'];}
?>
In HTML:
<div id='div_session_write'> </div>
The session is stored server-side so you cannot add values to it from JavaScript. All that you get client-side is the session cookie which contains an id. One possibility would be to send an AJAX request to a server-side script which would set the session variable. Example with jQuery's .post() method:
$.post('/setsessionvariable.php', { name: 'value' });
You should, of course, be cautious about exposing such script.
If you want to allow client-side manipulation of persistent data, then it's best to just use cookies. That's what cookies were designed for.
or by pure js, see also on StackOverflow :
JavaScript post request like a form submit
BUT WHY try to set $_session with js? any JS variable can be modified by a player with
some 3rd party tools (firebug), thus any player can mod the $_session[]! And PHP cant give js any secret codes (or even [rolling] encrypted) to return, it is all visible. Jquery or AJAX can't help, it's all js in the end.
This happens in online game design a lot. (Maybe a bit of Game Theory? forgive me, I have a masters and love to put theory to use :) ) Like in crimegameonline.com, I
initialize a minigame puzzle with PHP, saving the initial board in $_SESSION['foo'].
Then, I use php to [make html that] shows the initial puzzle start. Then, js takes over, watching buttons and modding element xy's as players make moves. I DONT want to play client-server (like WOW) and ask the server 'hey, my player want's to move to xy, what should I do?'. It's a lot of bandwidth, I don't want the server that involved.
And I can just send POSTs each time the player makes an error (or dies). The player can block outgoing POSTs (and alter local JS vars to make it forget the out count) or simply modify outgoing POST data. YES, people will do this, especially if real money is involved.
If the game is small, you could send post updates EACH move (button click), 1-way, with post vars of the last TWO moves. Then, the server sanity checks last and cats new in a $_SESSION['allMoves']. If the game is massive, you could just send a 'halfway' update of all preceeding moves, and see if it matches in the final update's list.
Then, after a js thinks we have a win, add or mod a button to change pages:
document.getElementById('but1').onclick=Function("leave()");
...
function leave() {
var line='crimegameonline-p9b.php';
top.location.href=line;
}
Then the new page's PHP looks at $_SESSION['init'] and plays thru each of the
$_SESSION['allMoves'] to see if it is really a winner. The server (PHP) must decide if it is really a winner, not the client (js).
You can't directly manipulate a session value from Javascript - they only exist on the server.
You could let your Javascript get and set values in the session by using AJAX calls though.
See also
Javascript and session variables
jQuery click event to change php session variable
One simple way to set session variable is by sending request to another PHP file. Here no need to use Jquery or any other library.
Consider I have index.php file where I am creating SESSION variable (say $_SESSION['v']=0) if SESSION is not created otherwise I will load other file.
Code is like this:
session_start();
if(!isset($_SESSION['v']))
{
$_SESSION['v']=0;
}
else
{
header("Location:connect.php");
}
Now in count.html I want to set this session variable to 1.
Content in count.html
function doneHandler(result) {
window.location="setSession.php";
}
In count.html javascript part, send a request to another PHP file (say setSession.php) where i can have access to session variable.
So in setSession.php will write
session_start();
$_SESSION['v']=1;
header('Location:index.php');
Not possible. Because JavaScript is client-side and session is server-side. To do anything related to a PHP session, you have to go to the server.
be careful when doing this, as it is a security risk. attackers could just repeatedly inject data into session variables, which is data stored on the server. this opens you to someone overloading your server with junk session data.
here's an example of code that you wouldn't want to do..
<input type="hidden" value="..." name="putIntoSession">
..
<?php
$_SESSION["somekey"] = $_POST["putIntoSession"]
?>
Now an attacker can just change the value of putIntoSession and submit the form a billion times. Boom!
If you take the approach of creating an AJAX service to do this, you'll want to make sure you enforce security to make sure repeated requests can't be made, that you're truncating the received value, and doing some basic data validation.
I solved this question using Ajax. What I do is make an ajax call to a PHP page where the value that passes will be saved in session.
The example that I am going to show you, what I do is that when you change the value of the number of items to show in a datatable, that value is saved in session.
$('#table-campus').on( 'length.dt', function ( e, settings, len ) {
$.ajax ({
data: {"numElems": len},
url: '../../Utiles/GuardarNumElems.php',
type: 'post'
});
});
And the GuardarNumElems.php is as following:
<?php
session_start();
if(isset ($_POST['numElems'] )){
$numElems = $_POST['numElems'];
$_SESSION['elems_table'] = $numElems;
}else{
$_SESSION['elems_table'] = 25;
}
?>

JavaScript EventSource listening for a Webhook pushed to PHP script

I've been searching and experimenting and I just can't seem to figure this out. I would appreciate any insight. Thank you!
So I have a Shopify store and I have an Webhook that triggers when I make a sale, meaning it pushes JSON data of that sale to a PHP script on my server. Right now I'm having that PHP script insert the relevant data into a database and mark that sale as "unread." Then, I would have a separate HTML/JavaScript page that I would run separately, polling the server to check for unread sales ever 10 seconds or so. There's a little more to that, but that's the general idea. It's clunky and I would like to modernize this.
Here's what I've been trying and can't seem to get working.
Set up an EventSource page that's listening to a separate PHP script.
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sales Notification!</title>
</head>
<body>
<div id="widget">
<div id="notification_box"></div>
</div>
<script type="text/javascript">
if (!!window.EventSource) {
var source = new EventSource('alert_listener.php');
} else {
console.log("Window.EventSource fail!");
}
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
source.addEventListener('open', function(e) {
// Connection was opened.
}, false);
source.addEventListener('error', function(e) {
if (e.readyState == EventSource.CLOSED) {
// Connection was closed.
}
}, false);
</script>
</body>
</html>
That actually works well when I do something simple like this example. Anyway, here's my PHP code listening for the JSON sent from the Websocket (some of this code is provided by Shopify):
<?php
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
error_reporting(0);
define('SHOPIFY_APP_SECRET', 'NOT_PUBLIC_HAR_HAR');
function verify_webhook($data, $hmac_header) {
$calculated_hmac = base64_encode(hash_hmac('sha256', $data, SHOPIFY_APP_SECRET, true));
return ($hmac_header == $calculated_hmac);
}
function sendMsg($id, $msg) {
echo "id: $id" . PHP_EOL;
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];
$data = file_get_contents('php://input');
$verified = verify_webhook($data, $hmac_header);
while (1) {
if ($data !== "") {
sendMsg("test id", "Data: " . $data);
}
sleep(1);
}
?>
When I push data from Shopify to this PHP script, the first JavaScript example is supposed to be listening for this data, but nothing happens. Not a thing. I have no idea why. I have no idea how to tell the PHP script to say, "Hey! An order came in! Yo JavaScript, do something!" and then the JavaScript go, "New order received! Let's do a thing!"
TLDR:
Shopify pushes JSON to a PHP script (via a webhook)
Separate JavaScript file listens to this PHP script via EventSource object and reacts accordingly
I can't get this to work. Please help.
That is all. Thank you.
I saw this on Twitter - and no, this can be answered.
First of I have to admit that I am not familiar all too well with EventSource - but from what I see, you are using exactly one script to do two things at once; obtaining the Shopify data and immediately exporting it to JS. However, each PHP script ran has exactly one request and response context - and in this case, you have been echo'ing your data all the way back to Shopify.
You will need two endpoints:
The first endpoint acts as the receipient to Shopify's webhooks (shopify_webhook.php). Each time it receives data, you might store it in a database for fire-and-forget actions like Redis, where you set a possibly low TTL. As far as I know, Redis also has queues - so this would probably be a better approach.
The second endpoint is your event source that keeps streaming incoming queue entries to your requesting JavaScript (i.e. shopify_eventsource.php).
Redis here is just a suggestion - but one way or another, you will have to use an intermediate storage to be able to move the incoming data to another output channel. You can write all this in one PHP file where you validate the incoming request to see if it is a Shopify request (and stream) or if it is your JavaScript code requesting the output. But using two endpoints and thus separating code might make it more readable and adjustable should Shopify change APIs or you your own JavaScript receipient.
TL;DR:
Shopify -> Your endpoint -> intermediate storage.
Intermediate storage -> your endpoint -(stream)> your javascript.

Constantly read JSON database

I want to constantly read a JSON-formatted js file so my page shows the changes of that file.
I want some content in my page to change everytime I change the database file within the directory.
My files are:
objectoJSON.js:
var rightFencer;
rightFencer = {"name":"Jorge ANZOLA","nacionality":"VEN","points":10};
var leftFencer;
leftFencer = {"name":"John DOE","nacionality":"USA","points":5};
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<center><p id="rightFencerName"></p><p id="rightFencerPoints"></p> - <p id="leftFencerName"></p> <p id="leftFencerPoints"></p></center>
<script src="objetoJSON.js"></script>
<script>
document.getElementById("rightFencerName").innerHTML = rightFencer.name;
document.getElementById("leftFencerName").innerHTML = leftFencer.name;
document.getElementById("rightFencerPoints").innerHTML = rightFencer.points;
document.getElementById("leftFencerPoints").innerHTML = leftFencer.points;
</script>
</body>
</html>
I thought about putting those two scripts into an infinite while loop so by the time I change the file in the directory, it'd change. But it didn't work.
Also, I thought about using setInterval() to run the scripts every few seconds, but I didn't know how to make it work.
As you can see, I'm a complete noob, so ANY idea would be very appreciated.
Your "objectoJSON.js" is not a JSON file... it's a simple javascript object.
A JSON file would be something like this.
{
"rightFencer":{
"name":"Jorge ANZOLA",
"nacionality":"VEN",
"points":10
},
"leftFencer":{
"name":"John DOE",
"nacionality":"USA",
"points":5
}
}
What you are searching for is
Ajax, Server Sent Events or webSockets
Those update the pagecontent without the need to refresh the page or clicking something.
The following codes shows how to interact with each technology.
They have many advantages and disadvantages... to many to write right now.
ask specific and i can add that to the answer.
All the following examples are pure javascript and so don't need any type of library.They work with almost all new browsers... ios,android,windows also.
All the following examples could be adapted to work with a non properly formatted json file like that you posted. Look at the bottom.
Ajax:
Client asks for data
This updates the client every 30seconds.
function $(a){
return document.getElementById(a)
}
function ajax(a,b,c){ // Url, Callback, just a placeholder
c=new XMLHttpRequest;
c.open('GET',a);
c.onload=b;
c.send()
}
function reloadData(){
ajax('database.js',updateText)
};
function updateText(){
var db=JSON.parse(this.response);
$("rightFencerName").innerHTML=db.rightFencer.name;
$("leftFencerName").innerHTML=db.leftFencer.name;
$("rightFencerPoints").innerHTML=db.rightFencer.points;
$("leftFencerPoints").innerHTML=db.leftFencer.points;
}
window.setInterval(reloadData,30000);//30 seconds
/*setinterval is a very bad way to update stuff ,
especially with ajax.. there are many other ways to do that.*/
Ajax does not need any type of server if you read the JS file locally.
Also appendding it... but both examples are time based... and that is not good if you have many users online. WS & SSE allow you to update each user individually depending on the necessity.
SSE:
Server sends data when needed
This uses php to create a Server Sent Events Server
Also this updates the client every 30 seconds, but in this case the server updates the client. Using Ajax the client asks the server to update.
The php file "sse.php"
header('Content-Type: text/event-stream'); // specific sse mimetype
header('Cache-Control: no-cache'); // no cache
while(true) {
if(/*something changes*/){
echo "id: ".time().PHP_EOL;
echo "data: ".$data.PHP_EOL;
echo PHP_EOL;
}
ob_flush(); // clear memory
flush(); // clear memory
sleep(30);// seconds
}
The javascript file
function $(a){
return document.getElementById(a)
}
function updateText(e){
var db=JSON.parse(e.data);
$("rightFencerName").innerHTML=db.rightFencer.name;
$("leftFencerName").innerHTML=db.leftFencer.name;
$("rightFencerPoints").innerHTML=db.rightFencer.points;
$("leftFencerPoints").innerHTML=db.leftFencer.points;
}
var sse=new EventSource("sse.php");
sse.onmessage=updateText;
WebSockets:
Server sends data when needed, Client asks for data when needed
webSockets is cool ... comunication is bidirectional. it is fast. but you need something like a nodejs server to be able to handle it properly.
function $(a){
return document.getElementById(a)
}
function updateText(e){
var db=JSON.parse(e.data);
$("rightFencerName").innerHTML=db.rightFencer.name;
$("leftFencerName").innerHTML=db.leftFencer.name;
$("rightFencerPoints").innerHTML=db.rightFencer.points;
$("leftFencerPoints").innerHTML=db.leftFencer.points;
}
var ws=new WebSocket('ws://YOURIP:YOURPORT');
/*ws.onopen=function(){ //those events are also aviable with sse
ws.send('WS open!');//sending data to the server
};
ws.onclose=function(){
console.log('WS closed!');
};*/
ws.onmessage=updateText;
Adapting the js
Ajax..
load the "objectoJSON.js" with ajax and evulate it ... but not using eval(). eval is evil. use new Function()
function updateText(){
document.getElementById("rightFencerName").innerHTML = rightFencer.name;
document.getElementById("leftFencerName").innerHTML = leftFencer.name;
document.getElementById("rightFencerPoints").innerHTML = rightFencer.points;
document.getElementById("leftFencerPoints").innerHTML = leftFencer.points;
}
(new Function(this.response+'\n updateText()'))();
or append the script every 30 seconds or whatever....
I don't write that example as it is the worst approach.
With 30 clients it means that you have to read the file from server evey second.
With SSE or WS you read it once and broadcast it to hundreds of clients.
I suggest to fix your json file.
if you have any other questions ask.
I guess you are working with framework which supports websockets.
You could listen for a change in file using websocket.it may return change in data set like new record or update on any record, or using javascript/ajax call get latest content from server and update your HTML.
https://www.websocket.org/demos.html, see foreign exchange dashboard to see how websockets can be used for constantly updating data.
The way you are doing it now isn't scalable, testable or manageable.
You really don't want to save data on the server using plaintext json files.
If you want a more robust framework for handling your use case, I suggest using web sockets on both the client side and server side (socket.io is a great choice), and using RethinkDB on your server as the DB.

Can we call a javascript function from WebService?

I have a situation where I have to call a a javascript method from SQL Server. I haven't found any solution to do the same. I found one thing that I can call web service from SQL Server but now the problem is "Can we call javascript function from web service (like we can do in code behind file of aspx page)"?
Please help
Well, it depends on what you mean. If I'm not mistaken the guys behind the free real-time communication platform, xSockets have been able to use a compiled stored procedure in SQL Server to use xSockets to dispatch a call to connected clients (e.g using WebSockets). I'm not saying this is something you should do, I'm saying "I think they have done it". You will find contact info on their page or just tweet with #xsockets hash on Twitter and they will respond.
You could do this using Server-Sent Events, which are supported in most recent browsers.
The PHP:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
echo "id: " . time() . " " . PHP_EOL;
echo "data: $message" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
The JS:
var source = new EventSource('/php');
source.onmessage = function(e) {
console.log(e.data);
};
You can "call" javascript directly from the webservice... Or more correctly spoken you can use a publish/subscribe pattern to publish a message from you webservice and subscribe to it in your javascript.
Like #Daniel says we (XSockets) have called javascript from a compiled stored procedure, but that was a few years ago... I think it will be easier for you to take the approach where you "call" the javascript from a webservice.
To do it between webservice and javascript could be something like this...
JAVASCRIPT
//Setup a subscription for the event 'foo'
conn.on('foo', function(data){
console.log('foo - some data arrived from the webservice', data);
});
C# (or VB if you want to)
//Connect to the realtime server and the default controller generic
var conn = ClientPool.GetInstance("ws://127.0.0.1:4502/Generic", "*");
//We send an anonymous message here, but any object will work.
conn.Send(new { Message = "Hello JavaScript from C#" },"foo");
Full example here
There may be some easier way to do this as well... if I knew a little bit more about what you are doing :)
No, you can't call a javascript function on the client from a web service on a server.

Categories

Resources