Firstly, I apologize if this issue has been posted before, I couldn't find the answer anywhere.
I'm writing a one page website that uses JavaScript, Ajax and PHP to take key presses and send them out via serial port.
I'm testing it on EasyPHP and WAMP, I'm yet to test on a Linux server.
My problem is that when keys are pressed rapidly I get the error below.
Warning: fopen(com4): failed to open stream: Permission denied in \keypresstest.php on line 7
If I press keys slowly, around 500ms intervals, it all works fine.
Furthermore, following the error above, PHP does not set my $fp variable, so it also returns errors:
Warning: fwrite() expects parameter 1 to be resource, boolean given in \keypresstest.php on line 9
Warning: fclose() expects parameter 1 to be resource, boolean given in \keypresstest.php on line 10
I think that there is slow 'release' of the serial port resource which it's defining as 'Resource id #3' and if I could some how speed this up or spawn another instance when needed i might be able to resolve the issue.
I hope someone reading this might have some advice.
My code is below, I've removed some components to keep this code more concise
HTML File
<script> <!-- call php script here -->
function sendKey(str) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("txtHint").innerHTML = document.getElementById("txtHint").innerHTML + xmlhttp.responseText;
}
}
xmlhttp.open("GET", "keypresstest.php?q=" + str, true);
xmlhttp.send();
}
</script>
<script> // page js key listener script
document.addEventListener('keydown', function(event) { // things happen as keys are pressed
if (!arrayContainsCheck(keysHeld, event.keyCode)) { // check if the key is already being held, this is so keydown events don't continue to propagate whilst a key is held
if(event.keyCode == 38 || event.keyCode == 87) { // up/w keys, send output to php script "f"
sendKey("f");
} keysHeld.push(event.keyCode);
}
});
document.addEventListener('keyup', function(event) {
document.getElementById("lightSwitch").style.backgroundColor = "blue";
if(event.keyCode == 38 || event.keyCode == 87) { // up/w keys, send output to php script "g"
document.getElementById("upArrow").style.border = "1px solid red";
sendKey("g");
}
keyRelease(keysHeld, event.keyCode);
});
</script>
PHP File
<?php
$q = $_REQUEST["q"]; // get the q parameter from URL
// Output q parameter to com4 serial port
echo "q is $q <br />";
echo "defining fp... <br />";
$fp = fopen("com4", "w");
echo "fp defined as " . $fp . " .<br />";
fwrite($fp, $q);
fclose($fp);
?>
Related
I have a Server Send Event working and updating a webpage. I then assign the contents of the div receiving the SSE to a var so as to send it to a php file to insert into a database. The div's data is constantly changing in sseReceiving.php page, but how to send it and it's changing values to the database dynamically. Now it is only sending the div content to the database when the page is re-submitted. How to do it continually?
sseTriggering.php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
//generate random number for demonstration
$new_data = rand(0, 1000);
//echo the new number
//echo "data: New random number:". $new_data. "\n\n";
echo "data:".$new_data."\n\n";;
flush();
sseReceiving.php
<body>
<div id="serverData">Here is where the server sent data will appear</div>
<script type="text/javascript">
//check for browser support
if(typeof(EventSource)!=="undefined") {
//create an object, passing it the name and location of the server side script
var eSource = new EventSource("sseTriggering.php");
//detect message receipt
eSource.onmessage = function(event) {
//write the received data to the page
document.getElementById("serverData").innerHTML = event.data;
var MyDiv = document.getElementById("serverData").innerHTML;
window.location.href = "findpair.php?pair=" + MyDiv;
};
}
</script>
</body>
findpair.php
$pair = $_GET['pair'];
$qX = "UPDATE product SET prod_name = '$pair' WHERE id = 1";
$rrr = mysqli_query ($dbc, $qX) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
I have researched this issue at the links below and some have helped me get it to the stage it is at now.
http://www.coderslexicon.com/the-basics-of-passing-values-from-javascript-to-php-and-back/
send javaScript variable to php variable
Get content of a DIV using JavaScript
Detect element content changes with jQuery
I have also put header('Refresh: 5'); in the php part of the various files and no change.
You should be able to send the request via AJAX for your main function which will allow the sse events to come to your client and then go to your findpair.php function.
if(typeof(EventSource)!=="undefined") {
//create an object, passing it the name and location of the server side script
var eSource = new EventSource("sseTriggering.php");
//detect message receipt
eSource.onmessage = function(event) {
//write the received data to the page
document.getElementById("serverData").innerHTML = event.data;
//Send AJAX request.
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
if (xmlhttp.status == 200) {
//Do something with 'xmlhttp.responseText' if you want.
}
else if (xmlhttp.status == 400) {
alert('There was an error 400');
} else {
alert('something else other than 200 was returned');
}
}
};
xmlhttp.open("GET", "findpair.php?pair=" + event.data, true);
xmlhttp.send();
};
}
More info here on submitting AJAX requests with javascript.
I have a web that draws a tree. inicio_pru.php creates a JSON which represents the tree.This JSON is passed to a JavaScript file for creting the tree.
inicio_pru.php, is called in two different moments, first , when the page is charged , it creates the JSON and passes it to example_pru.js in order this can draw it. 2nd, when the tree is already created, and user clicks a node of the tree, this invoques inicio_pru.php from example_pru.js with an object XMLHttpRequest and inicio_pru.php generates the JSON the same way as the 1rst time and this is sent to the XMLHttpRequest with an "echo" command.
It Works in the first case, but not in the second that generates the following error:
Unexpected token '
inicio_pru.php:
function main_p ($ID,$tipo_var,$desc_var,$idnodo,$t_ancestros) {
......
//Here, $arbol is saved in the correct format
if ($tipo_var=='BIFURCADORES'){
$file = fopen("archivo.txt", "w");
//$file = fopen($desc_var.".txt", "w");
fwrite($file, $arbol . PHP_EOL);
fclose($file);
}
return $arbol;
}
//main program
if (!is_null($idnodo)) {
// main_p , has saved $arbol with each field of the JSON in double quotes
$arbol=main_p($ID,$tipo_var,$desc_var,$idnodo,$t_ancestros);
//this sentence has saved $arbol at the discwith each field of the JSON without double quotes
exec('echo '.$arbol. ' >>/tmp/pista11', $output, $error);
//This is sent to example1_json_pru.js throght an objet XMLHttpRequest
echo $arbol;
}
else
$arbol=main_p($ID,$tipo_var,$desc_var,$idnodo,$t_ancestros);
As you can see, $arbol, is saved in two files:
archivo.txt , correct, it place each field in double quotes, but in pista11, fileds appear without these double quotes:
archivo.txt , (correct):
{"id":"53530","name":"Bifurcadores <ul ....
pista11 , (incorrect):
{id:53530,name:Bifurcadores <ul ......
In inicio_pru.php at the "else" sentence, $arbol is passed to another .php , that sends it to .js example_pru.js, and it works:
grafos_template_otro_json_fr_pru.php:
<!-- Files -->
<script language="javascript" type="text/javascript" src="../mapas/assets/js/example1_json_pru.js"></script>
<script type="text/javascript">
var datos=<?php echo $arbol ; ?>;
var ID=<?php echo $ID ; ?>;
var tipo_var=<?php echo $tipo_var ; ?>;
</script>
</head>
<body onload="init(datos,1,ID,tipo_var);">
(init is una function of example1_json_pru.js)
However, when init_pru.php is called from the XMLHttpRequest and it pases $arbol to example1_json_pru.js this way, it doesn't work, and generates the error mencioned before:
XMLHttpRequest:
onCreateLabel: function(label, node){
label.id = node.id;
label.innerHTML = node.name;
label.onclick = function(){
var http = new XMLHttpRequest();
var url = "inicio_pru.php";
var params = "idnodo="+ node.id + "&ID=" + ID + "&id_arbol=" + tipo_var;
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.send(params);
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
//astonishingly, alert shows the fields of the JSON in quotes despite pista11 (file saved just before sending $arbol XMLHttpRequest object), showed them wihthout double quotes
alert (http.responseText);
//This is the sentence that generates error:
json=JSON.parse(http.responseText);
st.loadJSON(json);
//compute node positions and layout
st.compute();
//optional: make a translation of the tree
st.geom.translate(new $jit.Complex(-200, 0), "current");
st.onClick(node.id);
}
}
};
Could you please help me? Thank you very much indeed
the issue is that your json has invalid format.
archivo.txt , (correct):
{"id":"53530","name":"Bifurcadores
pista11 , (incorrect):
{id:53530,name:Bifurcadores
in above example you can see you are missing " " in variables and values.
I am using the following code to determine if an m3u8 URL is broken or not. I test with two different URLs, one that is online and one that is offline. For both cases, my javascript function doesn't alert me that file is found or not and firefox debugs doesn't give me any error but status variable always shows 0. Could anyone tell me what I am doing wrong here?
Edit:
for offline url i get this header response(in httpfox developer tool) :HTTP/1.1 404 Not Found
for online url i get this header response(in httpfox developer tool) :HTTP/1.1 200 OK
Code:
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
function testFunction() {
//m="http://someothersite.com/offline.m3u8";
m="http://somesite.com/workingfile.m3u8";
//now we checking if the file exist
UrlExists(m, function(status){
alert('status:'+status);
if(status === 200){
// file was found
alert('file found'+m);
}
else if(status === 404){
// 404 not found
alert('file not found'+m);
}
});
function UrlExists(url, cb){
jQuery.ajax({
url: url,
dataType: 'text',
type: 'GET',
complete: function(xhr){
alert(+xhr.status);
if(typeof cb === 'function')
cb.apply(this, [xhr.status]);
}
});
}
}// end of main
</script>
</head>
<body>
<button onclick="testFunction()">Click me</button>
</html>
This will not work if you are using external URL's as CORS (Cross-origin resource sharing) will kick in and will stop you as you are not on the same domain.
Working version: local files only
UrlExists('/path/file.php', function(status){
if(status === 200){
alert('file found');
}
else if(status === 404){
alert('file not found');
}
});
Unfortunately, there isnt a valid way of doing this through Javascript. However, you can conduct this through backend functionality e.g. PHP
$file = 'http://www.othername.com/somefile.jpg';
$file_headers = #get_headers($file);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
$exists = false;
}
else {
$exists = true;
}
If you build this into a php function and then use your Ajax functionality to pass the URL through to the PHP for validation, and then return back a response - it should work.
Edit: Curl Example
$mainUrl = curl_init($url);
curl_setopt($mainUrl, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($mainUrl);
$httpCode = curl_getinfo($mainUrl, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
echo "404 Error";
}else if($httpCode == 200){
echo "200 Error";
}else{
echo "all good - sort off...";
}
curl_close($mainUrl);
Here is the Curl option - Now the way i would do it (and i really had to do it...) is looping through each and every single URL on the page (in js) and sending it as an object to PHP (through Ajax). With PHP, i would use the above CURL functionality to confirm which ones are broken (either with a 1 or 0) and then send a response back.
The following Ajax works , but it takes a while just to notify user on the client side that the username is already taken. Is there any ways to fasten this respons, or it's just normal behavior of Ajax.
Client :
<title>Choose a username</title>
<style>
#targetDiv {
background-color: #FF9999;
width: 40%;
}
</style>
<script type = "text/javascript">
var XMLHttpRequestObject = false;
if (window.XMLHttpRequest) {
XMLHttpRequestObject = new XMLHttpRequest();
} else if (window.ActiveXObject) {
XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
}
function getData(dataSource)
{
if(XMLHttpRequestObject) {
XMLHttpRequestObject.open("GET", dataSource);
XMLHttpRequestObject.onreadystatechange = function()
{
if (XMLHttpRequestObject.readyState == 4 &&
XMLHttpRequestObject.status == 200) {
if(XMLHttpRequestObject.responseText == "taken"){
var targetDiv = document.getElementById("targetDiv");
targetDiv.innerHTML = "<div>That username is taken.</div>";
}
}
}
XMLHttpRequestObject.send(null);
}
}
function checkUsername(keyEvent)
{
keyEvent = (keyEvent) ? keyEvent: window.event;
input = (keyEvent.target) ? keyEvent.target : keyEvent.srcElement;
if (keyEvent.type == "keyup") {
var targetDiv = document.getElementById("targetDiv");
targetDiv.innerHTML = "<div></div>";
if (input.value) {
getData("check.php?name=" +input.value);
}
}
}
</script>
</head>
<body>
<H1>Choose a username</H1>
Enter your new username <input id = "textField" type = "text"
name = "textField" onkeyup = "checkUsername(event)">
<div id = "targetDiv"><div></div></div>
</body>
</html>
Server
<?php
if ($_GET["name"] == "steve"){
echo "taken";
}
else {
echo "ok";
}
?>
Your question is "how to fasten the response".
The response is send by your server over the net.
The time taken for the net transfer will always vary.
But you can try to get faster responses of your server by optimizing the configuration of the webserver and PHP. You can test the response behavior of your server with a benchmark tool like abor siege.
And then tweak, test, compare results, repeat-until-satisfied.
A request to the server is a request to the server. No matter, if it is done by a browser via ajax or the benchmark tool.
For instance, upgrading to PHP 5.6 and enabling and tuning the opcache, gives quite a performance boost, when compared to let's say PHP 5.3. There a lot of optimizations possible. The question is too broad to go into detail.
When looking at the client-side JS: this is plain-vanilla JS.
Not much room for improvements. The only thing which comes to my mind is
to change the xhrObject for IE from "Microsoft.XMLHTTP, which is really old, to new ActiveXObject("Msxml2.XMLHTTP.6.0"); (and maybe add a fallback to new ActiveXObject("Msxml2.XMLHTTP.3.0");).
It will always take some time to get the respond from the server, you can tune up your server to be faster but you will always have a delay.
However what you can do is show a loading splash while you are connecting with the server.
You can also try storing usernames in Memcached as it will reduce the time taken for sql query.
Sorry for the really newbie question, just starting to learn AJAX.
I'd like to understand what exactly in the following causes the divMessage content to change continuously when "myName" text is changed.
1) It would seem that the Javascript function process is constantly "listening", is this normal Javscript behavior, or are there any triggers to call "process" repeatedly?
2) Is it true that any function that we assign to "body onload" will be executed repeatedly? How often is this repeated execution?
3) What if we want a single execution of the function process, how to do this?
4) I'm confused because I'm thinking the body will only load once. But is it because after "body onload" the function "process" is called, and the function process in turn modifies the "body" by changing the divMessage, essentially letting it go thru "body onload" again, then "process" again, etc.. ?
Thanks a lot in advance for your help!
<head>
<script type="text/javascript" src="quickstart.js"></script>
</head>
<body onload='process()'>
Server wants to know your name:
<input type="text" id="myName" />
<div id="divMessage" />
</body>
Here's quickstart.js processing parts
function process()
{
// proceed only if the xmlHttp object isn't busy
if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0)
{
// retrieve the name typed by the user on the form
name = encodeURIComponent(
document.getElementById("myName").value);
// execute the quickstart.php page from the server
xmlHttp.open("GET", "quickstart.php?name=" + name, true);
// define the method to handle server responses
xmlHttp.onreadystatechange = handleServerResponse;
// make the server request
xmlHttp.send(null);
}
}
// callback function executed when a message is received from the server
function handleServerResponse()
{
// move forward only if the transaction has completed
if (xmlHttp.readyState == 4)
{
// status of 200 indicates the transaction completed successfully
if (xmlHttp.status == 200)
{
xmlResponse = xmlHttp.responseXML;
xmlDocumentElement = xmlResponse.documentElement;
helloMessage = xmlDocumentElement.firstChild.data;
// display the data received from the server
document.getElementById("divMessage").innerHTML =
'<i>' + helloMessage+ '</i>';
}
}
}
and the quickstart.php
<?php
header('Content-Type: text/xml');
echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
echo '<response>';
$name = $_GET['name'];
// generate output depending on the user name received from client
$userNames = array('YODA', 'AUDRA', 'BOGDAN', 'CRISTIAN');
if (in_array(strtoupper($name), $userNames))
echo 'Hello, master ' . htmlentities($name) . '!';
else if (trim($name) == '')
echo 'Stranger, please tell me your name!';
else
echo htmlentities($name) . ', I don't know you!';
echo '</response>';
?>
Found the answer by shutting down and trying to run this again.
It turns out there was additional code that I commented out
but was cached that calls "process" every 1 second from handleServerResponse():
// display the data received from the server
document.getElementById("divMessage").innerHTML =
'<i>' + helloMessage+ '</i>';
setTimeout('process()', 1000);
Sorry about that. Lesson is to clear the browser cache before testing each code change :)
So I guess the advice to check if this function is called from any other place is correct.
Anyway, I read a great deal and learned a lot while trying to figure
this out. Thanks a lot #pst!