I'm trying to create a cron file in PHP. The application I've created has around 30 active users. I want each user to run a JavaScript web-worker periodically in the background which invokes a PHP file (via ajax/xmlhttprequest) that calls a PHP file to run.
Do JavaScript Web-Workers, when calling a PHP file via the Worker, block the main PHP requests from being executed, since they come from the same browser?
To do that you'll need to put an state to close the execution while a file is executing. Use callbacks on Workers to filter execution by status (can be HTTPs status) and close the socket listener while some callback isn't triggered or some state (some storage or variable) isn't filled by certain value.
Take the example from MDN page about Web Workers:
example.html: (the main page):
var myWorker = new Worker('my_task.js');
myWorker.onmessage = function(oEvent) {
//take current status from the worker from oEvent
status = oEvent.status;
console.log('Worker said : ' + oEvent.status);
};
//if ok, send an order to continue receiving php calls
if (status == 200)
//or other function
myWorker.postMessage('someorder');
my_task.js (the worker):
postMessage("Worker listening");
onmessage = function(oEvent) {
//if status is not ok, worker is busy and can't do anything
if (status != 200)
postMessage('Hi ' + oEvent.data);
};
You were so general that it's the only thing that came within my mind to solve your problem.
So I have a simple WebAPI Controller with...
[HttpGet]
public string Demo()
{
System.Diagnostics.Debug.Print("API Demo call hit " + DateTime.Now.ToString());
return "Got Here";
}
Because of the Debug output, I can tell that it is actually getting called from my javascript. So I know that my script is at least connecting. I also know that if I put a break on the line.. the script (html page) does pause and wait until I let the code continue. So they are talking, but I have 2 issues...
1) Every time I make a send call, I get the script error "NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://localhost:64769/api/demo'" ... even though I know it is talking to it. But I did notice that if I do NOT trap for errors, the script fails on the "Send" line and doesn't continue.
2) However, with the error trap, the script does continue (as expected) but the XMLHttpRequest doesn't have my return. (e.g. responseText is blank).. pretty much every single property of the object is blank or null.
So I think my response is empty because there is a problem with the "send". However because it is actually calling my Controller and waiting on it to run, I'm lost as to what the problem is?
Here is my script...
function CallWebAPI()
{
var displayResults = document.getElementById('responseDetails');
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "http://localhost:64769/api/demo", false);
try
{
xmlhttp.send();
}
catch(err)
{
displayResults.innerHTML += err + "<br />";
}
displayResults.innerHTML += "The Results...<br />";
for (var key in xmlhttp)
{
displayResults.innerHTML += key + "---" + xmlhttp[key] + "<br />";
}
}
All,
So after an entire day and half of messing around, finally figured it out. I guess I was running an HTML file from my desktop, and my Web Service was running on http://localhost:64769.
This is one of those cross domain things. When using an HTTP client in .NET, I did not have to deal with this.. but once I tried to use a client other than .NET, my Web service actually responded.. but the client Browser would not accept the response.
The fix was to change my api service to...
[HttpGet]
public HttpResponseMessage Demo()
{
string myReturnMessage = "API Demo call hit " + DateTime.Now.ToString();
System.Diagnostics.Debug.Print(myReturnMessage);
HttpResponseMessage myReturn = this.Request.CreateResponse(System.Net.HttpStatusCode.OK, myReturnMessage);
//This was the KEY!!!!
myReturn.Headers.Add("Access-Control-Allow-Origin", "*");
return myReturn;
}
Is there a way I can run a php function through a JS function?
something like this:
<script type="text/javascript">
function test(){
document.getElementById("php_code").innerHTML="<?php
query("hello"); ?>";
}
</script>
<a href="#" style="display:block; color:#000033; font-family:Tahoma; font-size:12px;"
onclick="test(); return false;"> test </a>
<span id="php_code"> </span>
I basically want to run the php function query("hello"), when I click on the href called "Test" which would call the php function.
This is, in essence, what AJAX is for. Your page loads, and you add an event to an element. When the user causes the event to be triggered, say by clicking something, your Javascript uses the XMLHttpRequest object to send a request to a server.
After the server responds (presumably with output), another Javascript function/event gives you a place to work with that output, including simply sticking it into the page like any other piece of HTML.
You can do it "by hand" with plain Javascript , or you can use jQuery. Depending on the size of your project and particular situation, it may be more simple to just use plain Javascript .
Plain Javascript
In this very basic example, we send a request to myAjax.php when the user clicks a link. The server will generate some content, in this case "hello world!". We will put into the HTML element with the id output.
The javascript
// handles the click event for link 1, sends the query
function getOutput() {
getRequest(
'myAjax.php', // URL for the PHP file
drawOutput, // handle successful request
drawError // handle error
);
return false;
}
// handles drawing an error message
function drawError() {
var container = document.getElementById('output');
container.innerHTML = 'Bummer: there was an error!';
}
// handles the response, adds the html
function drawOutput(responseText) {
var container = document.getElementById('output');
container.innerHTML = responseText;
}
// helper function for cross-browser request object
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req.readyState == 4) {
return req.status === 200 ?
success(req.responseText) : error(req.status);
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
The HTML
test
<div id="output">waiting for action</div>
The PHP
// file myAjax.php
<?php
echo 'hello world!';
?>
Try it out: http://jsfiddle.net/GRMule/m8CTk/
With a javascript library (jQuery et al)
Arguably, that is a lot of Javascript code. You can shorten that up by tightening the blocks or using more terse logic operators, of course, but there's still a lot going on there. If you plan on doing a lot of this type of thing on your project, you might be better off with a javascript library.
Using the same HTML and PHP from above, this is your entire script (with jQuery included on the page). I've tightened up the code a little to be more consistent with jQuery's general style, but you get the idea:
// handles the click event, sends the query
function getOutput() {
$.ajax({
url:'myAjax.php',
complete: function (response) {
$('#output').html(response.responseText);
},
error: function () {
$('#output').html('Bummer: there was an error!');
}
});
return false;
}
Try it out: http://jsfiddle.net/GRMule/WQXXT/
Don't rush out for jQuery just yet: adding any library is still adding hundreds or thousands of lines of code to your project just as surely as if you had written them. Inside the jQuery library file, you'll find similar code to that in the first example, plus a whole lot more. That may be a good thing, it may not. Plan, and consider your project's current size and future possibility for expansion and the target environment or platform.
If this is all you need to do, write the plain javascript once and you're done.
Documentation
AJAX on MDN - https://developer.mozilla.org/en/ajax
XMLHttpRequest on MDN - https://developer.mozilla.org/en/XMLHttpRequest
XMLHttpRequest on MSDN - http://msdn.microsoft.com/en-us/library/ie/ms535874%28v=vs.85%29.aspx
jQuery - http://jquery.com/download/
jQuery.ajax - http://api.jquery.com/jQuery.ajax/
PHP is evaluated at the server; javascript is evaluated at the client/browser, thus you can't call a PHP function from javascript directly. But you can issue an HTTP request to the server that will activate a PHP function, with AJAX.
The only way to execute PHP from JS is AJAX.
You can send data to server (for eg, GET /ajax.php?do=someFunction)
then in ajax.php you write:
function someFunction() {
echo 'Answer';
}
if ($_GET['do'] === "someFunction") {
someFunction();
}
and then, catch the answer with JS (i'm using jQuery for making AJAX requests)
Probably you'll need some format of answer. See JSON or XML, but JSON is easy to use with JavaScript. In PHP you can use function json_encode($array); which gets array as argument.
I recently published a jQuery plugin which allows you to make PHP function calls in various ways: https://github.com/Xaxis/jquery.php
Simple example usage:
// Both .end() and .data() return data to variables
var strLenA = P.strlen('some string').end();
var strLenB = P.strlen('another string').end();
var totalStrLen = strLenA + strLenB;
console.log( totalStrLen ); // 25
// .data Returns data in an array
var data1 = P.crypt("Some Crypt String").data();
console.log( data1 ); // ["$1$Tk1b01rk$shTKSqDslatUSRV3WdlnI/"]
I have a way to make a Javascript call to a PHP function written on the page (client-side script). The PHP part 'to be executed' only occurs on the server-side on load or refreshing'. You avoid 'some' server-side resources. So, manipulating the DOM:
<?PHP
echo "You have executed the PHP function 'after loading o refreshing the page<br>";
echo "<i><br>The server programmatically, after accessing the command line resources on the server-side, copied the 'Old Content' from the 'text.txt' file and then changed 'Old Content' to 'New Content'. Finally sent the data to the browser.<br><br>But If you execute the PHP function n times your page always displays 'Old Content' n times, even though the file content is always 'New Content', which is demonstrated (proof 1) by running the 'cat texto.txt' command in your shell. Displaying this text on the client side proves (proof 2) that the browser executed the PHP function 'overflying' the PHP server-side instructions, and this is because the browser engine has restricted, unobtrusively, the execution of scripts on the client-side command line.<br><br>So, the server responds only by loading or refreshing the page, and after an Ajax call function or a PHP call via an HTML form. The rest happens on the client-side, presumably through some form of 'RAM-caching</i>'.<br><br>";
function myPhp(){
echo"The page says: Hello world!<br>";
echo "The page says that the Server '<b>said</b>': <br>1. ";
echo exec('echo $(cat texto.txt);echo "Hello world! (New content)" > texto.txt');echo "<br>";
echo "2. I have changed 'Old content' to '";
echo exec('echo $(cat texto.txt)');echo ".<br><br>";
echo "Proofs 1 and 2 say that if you want to make a new request to the server, you can do: 1. reload the page, 2. refresh the page, 3. make a call through an HTML form and PHP code, or 4. do a call through Ajax.<br><br>";
}
?>
<div id="mainx"></div>
<script>
function callPhp(){
var tagDiv1 = document.createElement("div");
tagDiv1.id = 'contentx';
tagDiv1.innerHTML = "<?php myPhp(); ?>";
document.getElementById("mainx").appendChild(tagDiv1);
}
</script>
<input type="button" value="CallPHP" onclick="callPhp()">
Note: The texto.txt file has the content 'Hello world! (Old content).
The 'fact' is that whenever I click the 'CallPhp' button I get the message 'Hello world!' printed on my page. Therefore, a server-side script is not always required to execute a PHP function via Javascript.
But the execution of the bash commands only happens while the page is loading or refreshing, never because of that kind of Javascript apparent-call raised before. Once the page is loaded, the execution of bash scripts requires a true-call (PHP, Ajax) to a server-side PHP resource.
So, If you don't want the user to know what commands are running on the server:
You 'should' use the execution of the commands indirectly through a PHP script on the server-side (PHP-form, or Ajax on the client-side).
Otherwise:
If the output of commands on the server-side is not delayed:
You 'can' use the execution of the commands directly from the page (less 'cognitive' resources—less PHP and more Bash—and less code, less time, usually easier, and more comfortable if you know the bash language).
Otherwise:
You 'must' use Ajax.
I'm currently have an issue creating a webapp. All of the pages that we are creating can be viewed through a function that gets the post data and displays it onto the page. The issue I'm having is that when loading the content, the corresponding JS for sockets does not execute.
I believe this is because we're using:
socket.on("connect")
and the connect event would only fire once, but I'm unsure about how to fix this.
An example of the JS I'm currently using can be seen below.
function runJs(){
var url = document.location.pathname.toLowerCase();
if(url == '/account/create'){
var socket = io();
//once the socket connects, make calls
socket.on("connect", function(){=
socket.on("accountCreated", function(data){
if(typeof data.data.error !== "undefined"){
jQuery("#error").text(data.data.error);
}
else{
//account creation was successful and we're logged in.
//redirect to the home page
window.location.href = "/";
}
});
});
}
When executing another function (not posted here, as it's not important), it updates the pages HTML and runs the runJs() function seen above. I have confirmed through console.log that the function is indeed being called, but the code within the socket.on does not execute unless the page is reloaded.
Does anyone have any ideas about how I could fix this?
I'm currently programming in JSP and Javascript. (I am by no means an expert in either). Right now, what I want is for a Javascript function to be called repeatedly and one of the variables to be queried from the database repeatedly (it is the date that the page was last modified). If this variable is greater than when the page was loaded, I want the page to refresh.
What I have so far:
...
<body onload="Javascript:refreshMethod()">
<script type="text/JavaScript">
<!--
function refreshMethod()
{
var interval = setInterval("timedRefresh()", 10000);
}
function timedRefresh() {
var currenttime = '<%=currentTime%>';
var feedlastmodified = '<%=EventManager.getFeedLastModified(eventID)%>';
var currenttimeint = parseInt(currenttime);
var feedlastmodifiedint = parseInt(feedlastmodified);
if(feedlastmodifiedint > currenttimeint)
{
alert(feedlastmodifiedint);
setTimeout("location.reload(true);",timeoutPeriod);
}
if(feedlastmodifiedint < currenttimeint)
{
alert(feedlastmodifiedint + " : " + currenttimeint);
}
}
// -->
</script>
The problem is that everytime the timedRefresh runs, the feedlastModifiedInt never changes (even if it has been changed).
Any help would be appreciated,
Thanks.
The JSP code within the <% ... %> tags runs only once, on the server-side, when the page is loaded. If you look at the source of the page in the browser, you will find that these values have already been placed within the JavaScript code, and thus they will not change during each timer interval.
To update the data as you are expecting, you can use AJAX. You can find plenty of tutorials online.
JSP and JavaScript doesn't run in sync as you seem to expect from the coding. JSP runs at webserver, produces a bunch of characters which should continue as HTML/CSS/JS and the webserver sends it as a HTTP response to the webbrowser as response to a HTTP request initiated by the webbrowser. Finally HTML/CSS/JS runs at the webbrowser.
If you rightclick the page in webbrowser and choose View Source, you'll probably understand what I mean. There's no single line of Java/JSP code. It has already done its job of generating the HTML/CSS/JS. The only communication way between Java/JSP and JavaScript is HTTP.
You need to move this job to some servlet in the server side and let JS invoke this asynchronously ("in the background"). This is also known as "Ajax". Here's a kickoff example with a little help of jQuery.
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
var refreshInterval = setInterval(function() {
$.getJSON('refreshServlet', function(refresh) {
if (refresh) {
clearInterval(refreshInterval);
location.reload(true);
}
});
}, 10000);
});
</script>
Where the doGet() method of the servlet which is mapped on an url-pattern of /refreshServlet roughly look like this:
response.setContentType("application/json");
if (EventManager.getFeedLastModified(eventID) > currentTime) {
response.getWriter().write("true");
} else {
response.getWriter().write("false");
}
See also:
Communication between Java/JSP/JSF and JavaScript