Can we call a javascript function from WebService? - javascript

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.

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?

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.

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

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

Call a javascript function from php [duplicate]

How to call a JavaScript function from PHP?
<?php
jsfunction();
// or
echo(jsfunction());
// or
// Anything else?
The following code is from xyz.html (on a button click) it calls a wait() in an external xyz.js. This wait() calls wait.php.
function wait()
{
xmlhttp=GetXmlHttpObject();
var url="wait.php"; \
xmlhttp.onreadystatechange=statechanged;
xmlhttp.open("GET", url, true);
xmlhttp.send(null);
}
function statechanged()
{
if(xmlhttp.readyState==4) {
document.getElementById("txt").innerHTML=xmlhttp.responseText;
}
}
and wait.php
<?php echo "<script> loadxml(); </script>";
where loadxml() calls code from another PHP file the same way.
The loadxml() is working fine otherwise, but it is not being called the way I want it.
As far as PHP is concerned (or really, a web server in general), an HTML page is nothing more complicated than a big string.
All the fancy work you can do with language like PHP - reading from databases and web services and all that - the ultimate end goal is the exact same basic principle: generate a string of HTML*.
Your big HTML string doesn't become anything more special than that until it's loaded by a web browser. Once a browser loads the page, then all the other magic happens - layout, box model stuff, DOM generation, and many other things, including JavaScript execution.
So, you don't "call JavaScript from PHP", you "include a JavaScript function call in your output".
There are many ways to do this, but here are a couple.
Using just PHP:
echo '<script type="text/javascript">',
'jsfunction();',
'</script>'
;
Escaping from php mode to direct output mode:
<?php
// some php stuff
?>
<script type="text/javascript">
jsFunction();
</script>
You don't need to return a function name or anything like that. First of all, stop writing AJAX requests by hand. You're only making it hard on yourself. Get jQuery or one of the other excellent frameworks out there.
Secondly, understand that you already are going to be executing javascript code once the response is received from the AJAX call.
Here's an example of what I think you're doing with jQuery's AJAX
$.get(
'wait.php',
{},
function(returnedData) {
document.getElementById("txt").innerHTML = returnedData;
// Ok, here's where you can call another function
someOtherFunctionYouWantToCall();
// But unless you really need to, you don't have to
// We're already in the middle of a function execution
// right here, so you might as well put your code here
},
'text'
);
function someOtherFunctionYouWantToCall() {
// stuff
}
Now, if you're dead-set on sending a function name from PHP back to the AJAX call, you can do that too.
$.get(
'wait.php',
{},
function(returnedData) {
// Assumes returnedData has a javascript function name
window[returnedData]();
},
'text'
);
* Or JSON or XML etc.
I always just use echo "<script> function(); </script>"; or something similar. You're not technically calling the function in PHP, but this is as close as you're going to get.
Per now (February 2012) there's a new feature for this. Check here
Code sample (taken from the web):
<?php
$v8 = new V8Js();
/* basic.js */
$JS = <<< EOT
len = print('Hello' + ' ' + 'World!' + "\\n");
len;
EOT;
try {
var_dump($v8->executeString($JS, 'basic.js'));
} catch (V8JsException $e) {
var_dump($e);
}
?>
You can't. You can call a JS function from HTML outputted by PHP, but that's a whole 'nother thing.
If you want to echo it out for later execution it's ok
If you want to execute the JS and use the results in PHP use V8JS
V8Js::registerExtension('say_hi', 'print("hey from extension! "); var said_hi=true;', array(), true);
$v8 = new V8Js();
$v8->executeString('print("hello from regular code!")', 'test.php');
$v8->executeString('if (said_hi) { print(" extension already said hi"); }');
You can refer here for further reference:
What are Extensions in php v8js?
If you want to execute HTML&JS and use the output in PHP http://htmlunit.sourceforge.net/ is your solution
Thats not possible. PHP is a Server side language and JavaScript client side and they don't really know a lot about each other. You would need a Server sided JavaScript Interpreter (like Aptanas Jaxer). Maybe what you actually want to do is to use an Ajax like Architecture (JavaScript function calls PHP script asynchronously and does something with the result).
<td onClick= loadxml()><i>Click for Details</i></td>
function loadxml()
{
result = loadScriptWithAjax("/script.php?event=button_clicked");
alert(result);
}
// script.php
<?php
if($_GET['event'] == 'button_clicked')
echo "\"You clicked a button\"";
?>
I don't accept the naysayers' answers.
If you find some special package that makes it work, then you can do it yourself! So, I don't buy those answers.
onClick is a kludge that involves the end-user, hence not acceptable.
#umesh came close, but it was not a standalone program. Here is such (adapted from his Answer):
<script type="text/javascript">
function JSFunction() {
alert('In test Function'); // This demonstrates that the function was called
}
</script>
<?php
// Call a JS function "from" php
if (true) { // This if() is to point out that you might
// want to call JSFunction conditionally
// An echo like this is how you implant the 'call' in a way
// that it will be invoked in the client.
echo '<script type="text/javascript">
JSFunction();
</script>';
}
Ordering It is important that the function be declared "before" it is used. (I do not know whether "before" means 'lexically before' or 'temporally before'; in the example code above, it is both.)
try like this
<?php
if(your condition){
echo "<script> window.onload = function() {
yourJavascriptFunction(param1, param2);
}; </script>";
?>
you can try this one also:-
public function PHPFunction()
{
echo '<script type="text/javascript">
test();
</script>';
}
<script type="text/javascript">
public function test()
{
alert('In test Function');
}
</script>
PHP runs in the server. JavaScript runs in the client. So php can't call a JavaScript function.
You may not be able to directly do this, but the Xajax library is pretty close to what you want. I will demonstrate with an example. Here's a button on a webpage:
<button onclick="xajax_addCity();">Add New City</button>
Our intuitive guess would be that xajax_addCity() is a Javascript function, right? Well, right and wrong. The cool thing Xajax allows is that we don't have any JS function called xajax_addCity(), but what we do have is a PHP function called addCity() that can do whatever PHP does!
<?php function addCity() { echo "Wow!"; } ?>
Think about it for a minute. We are virtually invoking a PHP function from Javascript code!
That over-simplified example was just to whet the appetite, a better explanation is on the Xajax site, have fun!
For some backend node processing, you can run JS script via shell and return the result to PHP via console.log
function executeNode($script)
{
return shell_exec('node -e \'eval(Buffer.from("'.base64_encode($script).'", "base64").toString())\'');
}
$jsCode = 'var a=1; var b=2; console.log(a+b);';
echo executeNode($jsCode);

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.

Categories

Resources