Ajax call/response too long - php

First sorry for my bad english, i'm a new user but i read long ago this site and help me many problem resolve. Thanks all for this. Now unfortunately i dont find resolve for my problem.
I dont know why 2000 ms my all ajax call. All at same what thing the called .php file.
I try a lot of technique to resolve this but not help.
The task is refresh many div content in "real time" with database syncronization.
The site contains some timer. When the timer text equal 00:00:00 i call the update script.
my ajax call:
$(function() {
function update()
{
$.ajax({
type: "GET",
url: "ajax/update.php",
async: true,
success: function() {
update();
}
});
}
update();
});
my update php:
include 'inc/config.php';
include 'inc/conn/connopn.php';
$sDataForSync = "";
$iRowsNum = 0;
$sGetDataQuery = mysql_query("select `AID`, `PN` FROM `my_table1`;");
if (mysql_num_rows($sGetDataQuery ) > 0) {
while ($row = mysql_fetch_array($sGetDataQuery )) {
$iRowsNum++;
if ($iRowsNum == mysql_num_rows($sGetDataQuery )) {
$sDataForSync .= $row['AID'] . "|" . $row['PN'];
} else {
$sDataForSync .= $row['AID'] . "|" . $row['PN'] . PHP_EOL;
}
}
}
file_put_contents("updates.txt",$sDataForSync );
/* for now only write to text file, but later i would like to update in database */
include 'inc/conn/conncls.php';
The table contains max 30-40 rows and i using indexes, but still 2 seconds the response.
I need 200-400 ms, max 500ms responsetime with prospective mysql update query.
firefox results
Please help me decreases the time.
Thanks for all!

SOLVED. 1 sec is my fail. I left the second parameter from mysql_query. mysql_query("select",$dbconn); The another second is my web server fail. Too slowly. The mysql_connect(); is 1 second in localhost but on the remote server the full operation is 50-80 ms. Thanks for all the posts.

Related

Ajax/PHP long-polling results in 503 error

I'm playing around with AJAX long-polling and trying to read/update a simple counter (number) value in an MySQL cell by clicking on a button.
The PHP creates an infinite while loop and is checking if the value in the according cell has been modified (MySQL "current_timestamp", UNIX). If it has and the current_timestamp value is bigger then the timestamp the AJAX call was made, it's breaking the loop and sending the updated value and the updated current_timestamp to the client. The AJAX processes the data.
The Problem: It works but after a while I get a 503 error. I guess it's obviously the while loop or other open connections through multiple windows in other browsers (for testing).
PHP-File text.php:
// Connect to database
$con = mysql_connect('XX', 'XX', 'XX');
if (!$con)
{
die('Error' . mysql_error());
}
mysql_select_db('X', $con);
// Get data
$query = mysqli_query("SELECT counter_value, last_modified FROM content WHERE X = 'X' ORDER BY X DESC");
// Start infinite loop
set_time_limit(0);
while (true)
{
// The timestamp of the last ajax call = the last modified timestamp
$last_ajax_call = $_GET['timestamp'];
clearstatcache();
// Get the value of the counter and the last modified timestamp
while($row = mysql_fetch_array($query))
{
$counter_value = $row['counter_value'];
$last_modified= strtotime($row['last_modified']);
}
// If the time of the last modified timestamp is bigger/later than the last ajax call
if ($last_modified > $last_ajax_call)
{
$result = array(
'counter_value' => $counter_value,
'timestamp' => $last_modified
);
$json = json_encode($result);
echo $json;
break;
// If not, try again in 3 seconds
} else
{
sleep(3);
continue;
}
}
// Close database
mysql_close($con);
AJAX Part in js-File:
function getContent()
{
// get timestamp of last modified stored in attribute. The initial/first timestamp attribute is set beforehand.
var timestamp = $('#timestamp').attr('data-timestamp');
$.ajax(
{
type: 'GET',
url: 'test.php',
async: true,
cache: false,
data: {timestamp:timestamp},
success: function(data){
var obj = jQuery.parseJSON(data);
$("#counter").text(obj.counter_value);
$("#timestamp").attr("data-timestamp", obj.timestamp);
getContent();
}
}
);
}
getContent();
So the result is a 503 error which goes away after ca. 10 Minutes and it's working again.
(Any typos/formatting might be the result of cleaning up the code.)
I just started learning PHP and JS, so there might be a few newbie mistakes or weird lines in there, please be nice. Any advice on optimising the code is very appreciated!
It dies because PHP doesn't work the way you think it does.
You have intentionally put an infinite loop into your php in the assumption it will make your code keep looping around and rechecking the next GET request on each loop.
The reality is that the code is executed once for each request, and until execution of the code completes the server doesn't respond.
AJAX long polling requires no special handling in php, it's just an AJAX request in a loop. You might want to include a slight delay in your AJAX code otherwise your server will be hammered with requests.
To be honest this isn't what long polling is for, the idea of it is to update pages without any user interaction to display unread message notifications etc.
If you want to monitor user events like button clicks then bind your AJAX function to the clicking of the button.

Update php query limit whit js when load more

Hi I'm working on a reverse infinite scroll for a private message module.
The think is everything is working okay, my only problem is that I am not being able to update the limit of the query I am using.
The thing is a create the max and limit in php:
$max = mysql_num_rows($q_mensajes_contador_cargar);
$limit = $max-5;
Then when I use the infinite scroll I send the max and limit this way
$.ajax({
url: "formularios/cargar_mensajes.php?id=<? echo $id_receptor;?>&limite=<? echo $limit;?>",
success: function (html) {
if (html) {
$("#profile-feed-1").prepend(html);
$('div#loadmoreajaxloader').hide();
} else {
$('div#loadmoreajaxloader').html('<center>No more posts to show.</center>');
}
}
});
The thing is when I get this values in cargar_mensajes.php it just works once cause it is continually updating the same thing over and over, I want it to detect when it printed the next messages and update the query to show more or not show more depending in how many times it updates.
Sorry for my english...
Any advice, my js level is basic and I am sure that the way I am thinking this must not be the correct, just would like to know how can I achieve this.
Thank you!
You're setting the limit using PhP, so it never changes.
What you could do is :
var limit = <?php echo $limit; ?>
...
url: "formularios/cargar_mensajes.php?id=<? echo $id_receptor;?>&limite=" + limit,
success: function(html)
{
limit = limit + 5; // (Or -5, or whatever you need.)
Tell me if you need a more detailled code.

Real time data updates with comet and PHP?

I'm looking to implement real time notification updates on my social networking website. I have done some research on comet and i'm really fascinated by it.
From what I understand, this is the basic flow of what happens on a comet server.
Webpage:
Sends an ajax request to server when the document is ready.
Server:
Queries the database every x amount of seconds and returns a json string containing results if any are found.
Webpage:
Receives the result of the json string from the server and sends out another ajax request to do the above process again.
By understanding the flow of how comet works, I've written some PHP and Javascript code.
The JavaScript code uses the jQuery library and sends an ajax request out to the server with the current time in a unix timestamp format as a GET parameter.
$(document).ready(function(){
var timestamp = Math.round(new Date().getTime() / 1000);
function comet2(){
$.ajax({
type : 'GET',
url : 'comet.activities.php?timestamp=' + timestamp,
async : true,
cache : false,
success : function(data) {
alert("current timestamp "+timestamp)
var json = JSON.parse(data);
if(json !== null){
alert(data);
}
timestamp = json[0].timestamp;
setTimeout('comet2()', 1000);
},
error : function(XMLHttpRequest, textstatus, error) {
setTimeout('comet2()', 15000);
}
});
}
//call the comet function because the page has loaded.
comet2();
});
The PHP code will query for new activities by searching the database for new rows by using a timestamp paramater (in this case, a unix timestamp in a query). For this example, I have limited the amount of results to 1.
<?php
set_time_limit(0);
include("models/config.php");
global $mysqli,$db_table_prefix;
$last = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
$results = null;
$flag=true;
$stmt = $mysqli->prepare("SELECT id,timestamp FROM uc_user_activity WHERE timestamp > ? ORDER BY timestamp DESC LIMIT 0,1");
$stmt->bind_param("i", $last);
$stmt->bind_result($id,$timestamp);
while($flag){
$stmt -> execute();
while ($row = $stmt->fetch()){
$flag = false;
$results[] = array(
"id" => $id,
"timestamp" => $timestamp
);
}
$stmt -> close();
usleep(100000);
clearstatcache();
}
echo json_encode($results);
?>
The code above doesn't actually 'work' The problem is that if a user posts a new comment, it will fail to add to the database when the comet script is running. This means that the comet script will never return any json result because the statement in the sql query is never met (no new activities are added with a newer timestamp). My ajax code for posting new comments is working 100%, so I know that isn't the problem. Simply 'nothing happens', that is - nothing (no errors) are alerted or outputted to the browser console.
Edit number 3:
I'm seriously struggling to explain what I mean by 'nothing is happening', so I have uploaded an image showing that the database insert fails when the comet script is being called from jquery (notice how the textbox is disabled whilst the comment is being posted via ajax).
What can I do about this? I've spent hours searching the internet trying to fix this/find a similar working example with no avail.
If I change the query in my PHP code to be:
$stmt = $mysqli->prepare("SELECT id,timestamp FROM uc_user_activity WHERE timestamp **<** ? ORDER BY timestamp DESC LIMIT 0,1");
instead of:
$stmt = $mysqli->prepare("SELECT id,timestamp FROM uc_user_activity WHERE timestamp > ? ORDER BY timestamp DESC LIMIT 0,1");
results are instantly alerted to the browser window, comments can be posted again and the script is called again and new posts are displayed. This shows that my code 'is working' fine afterall and it looks like the query is causing the problem...
Can anyone see what is going on here? I have edited this question 7 times now and any guidance would be great as I'm just getting nowhere.
Just so this doesn't get closed, here is my question to round up what I have discussed above:
Are there any better ways of implementing a comet server? I'm not the
most experienced guy ever, but I would really like to learn how to do
this. It seems StackOverflow has this functionality and it works
perfectly - how are they doing it?
I can't possibly write my post in any further detail than this and I would REALLY appreciate some guidance from you awesome people. A suggestion as to why my code 'isn't working' or links to any tutorials explaining how to implement this would be amazing! Thanks in advance and apologies for this monster of a question and all of the edits!
My hunch is that the timestamp value which you are passing returns no results. You get the current time through Javascript. The query queries for all posts after this timestamp.
Can you try to print the query and run the same query manually to ensure that it retrieves data from the DB?
So, for the best available tutorial for Comet with PHP is here.
http://www.zeitoun.net/articles/comet_and_php/start
Like it, if it helps :)
For those who want to use the simple chat solution above in the link with jQuery here is the solution.
<script type="text/javascript">
var Comet = {};
Comet.jquery = {
timestamp: 0,
url: './backend.php',
noerror: true,
initialize: function () {
},
connect: function ()
{
this.ajax = $.ajax({
type: "get",
url: this.url,
data: {timestamp: this.timestamp},
success: function (data) {
// handle the server response
var response = JSON.parse(data);
console.log(response);
//alert(response.timestamp);
Comet.jquery.timestamp = response.timestamp;
Comet.jquery.handleResponse(response);
Comet.jquery.noerror = true;
},
complete: function (data) {
// send a new ajax request when this request is finished
if (!Comet.jquery.noerror) {
// if a connection problem occurs, try to reconnect each 5 seconds
setTimeout(function () {
Comet.jquery.connect()
}, 5000);
}
else {
Comet.jquery.connect();
}
Comet.jquery.noerror = false;
}
});
},
disconnect: function ()
{
},
handleResponse: function (response)
{
$('#content').append('<div>' + response.msg + '</div>');
},
doRequest: function (request)
{
$.ajax({
type: "get",
url: this.url,
data: {'msg': request}
});
}
}
</script>

Refresh div, but only if there is new content from php file

Background Info
I'm fiddling around with some PHP and AJAX at the moment, to try and get the code working for an auto refreshing div (every 10 seconds), that contains comments.
Here is javascript code I am using to refresh the div..
<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
$.ajaxSetup({ cache: false });
setInterval(function() {
$('#content_main').load('/feed_main.php');
}, 5000);
});
// ]]></script>
The code that will populate the div called "content_main", which is in feed_main.php, essentially accesses the database and echo's out the latest comments ...
Question
Is it possible, to only load the div "content_main" if the data inside of it, hasn't changed since the last time it was loaded?
My logic
Because I'm relatively new to javascript and AJAX I don't quite know how to do this, but my logic is:
For the first time it is run..
load data from feed_main.php file
Create a unique value (perhaps a hash value? ) to identify say 3 unique comments
Every other time it is run...
load the data from feed_main.php file
create a NEW unique value
check this value with the previous one
if they're the same, don't refresh the div, just leave things as they are, but if they're different then refresh..
The reason why I want to do this is because the comments usually have pictures attached, and it is quite annoying to see the image reload every time.
Any help with this would be greatly appreciated.
I've faced similar problem not too long ago, i assume that you using mysql or something for your comments storage serverside ?
I solved my problem by first adding timestamp integer column to my mysql table, then when i added a new row, i'd just simply use time() to save the current time.
mysql row insert example:
$query = "INSERT INTO comments (name, text, timestamp) VALUES ('". $name ."', '". $text ."',". time() .");";
step two would be to json_encode the data you sending from serverside:
$output = array();
if ($html && $html !== '') { // do we have any script output ?
$output['payload'] = $html; // your current script output would go in this variable
}
$output['time'] = time(); // so we know when did we last check for payload update
$json = json_encode($output, ((int)JSON_NUMERIC_CHECK)); // jsonify the array
echo $json; // send it to the client
So, now instead of pure html, your serverside script returns something like this:
{
"payload":"<div class=\"name\">Derpin<\/div><div class=\"msg\">Foo Bar!<\/div>",
"time":1354167493
}
You can grab the data in javascript simply enough:
<script type="text/javascript"> // <![CDATA[
var lastcheck;
var content_main = $('#content_main');
pollTimer = setInterval(function() {
updateJson();
}, 10000);
function updateJson() {
var request = '/feed_main.php?timestamp='+ (lastcheck ? lastcheck : 0);
$.ajax({
url: request,
dataType: 'json',
async: false,
cache: false,
success: function(result) {
if (result.payload) { // new data
lastcheck = result.time; // update stored timestamp
content_main.html(result.payload + content_main.html()); // update html element
} else { // no new data, update only timestamp
lastcheck = result.time;
}
}
});
}
// ]]> </script>
that pretty much takes care of communication between server and client, now you just query your database something like this:
$timestamp = 0;
$where = '';
if (isset($_GET['timestamp'])) {
$timestamp = your_arg_sanitizer($_GET['timestamp']);
}
if ($timestamp) {
$where = ' WHERE timestamp >= '.$timestamp;
}
$query = 'SELECT * FROM comments'. $where .' ORDER BY timestamp DESC;';
The timestamps get passed back and forth, client always sending the timestamp returned by the server in previous query.
Your server only sends comments that were submitted since you checked last time, and you can prepend them to the end of the html like i did. (warning: i have not added any kind of sanity control to that, your comments could get extremely long)
Since you poll for new data every 10 seconds you might want to consider sending pure data across the ajax call to save substantial chunk bandwidth (json string with just timestamp in it, is only around 20 bytes).
You can then use javascript to generate the html, it also has the advantage of offloading lot of the work from your server to the client :). You will also get much finer control over how many comments you want to display at once.
I've made some fairly large assumptions, you will have to modify the code to suit your needs. If you use my code, and your cat|computer|house happens to explode, you get to keep all the pieces :)
How about this:
<script type="text/javascript">
// <![CDATA[
$(function () {
function reload (elem, interval) {
var $elem = $(elem);
// grab the original html
var $original = $elem.html();
$.ajax({
cache : false,
url : '/feed_main.php',
type : 'get',
success : function (data) {
// compare the result to the original
if ($original == data) {
// just start the timer if the data is the same
setTimeout(function () {
reload(elem, interval)
}, interval);
return;
}
// or update the html with new data
$elem.html(data);
// and start the timer
setTimeout(function () {
reload(elem, interval)
}, interval);
}
});
}
// call it the first time
reload('#content_main', 10000);
});
// ]]>
</script>
This is just an idea to get you going it doesn't deal with errors or timeouts.
Best And Easy Code
setInterval(function()
{
$.ajax({
type:"post",
url:"uourpage.php",
datatype:"html",
success:function(data)
{
$("#div").html(data);
}
});
}, 5000);//time in milliseconds

Mysql query overloading VPS

I have a text based game site (Mafia game) written in old php/mysql style. I have no to very less knowledge of PHP/MYSQL i am learning it though. So i am having problems with one of file which reloads every 5 second via ajax , it contains few Mysql query which checks messages, forum messages,transfer,attacks etc and depending on the check it shows alert to users if they get any new message,forum messages,transfer,attacks etc. My site is using VPS right now and if i set the refresh rate to 5 seconds it overlaods the VPS within few minutes so i have to set the refresh time to 20 seconds or more. I would like to know if there is any problems with query or any suggestion to optimize query/php code. Below is code of my file ajax.php which needs to be reloaded every 5 seconds
<?php
include("funcs.php");
global $tab, $time, $id, $tru, $old;
$round=$_GET['tru'];
$tO=0;
$moFo='r'.$round.'_mafiosi';
$brd=$tab['board'];
$query="select msg,atk,ivt,transf from $moFo where id='$id'";
$result=mysql_query($query);
$ans=mysql_fetch_assoc($result);
foreach($ans as $key=>$value)
{
$tO+=$value;
}
$rtn='#'.$mafioMsg;
echo "$tO$rtn";
?>
#
and below is the jquery/javascript i am using :
<script type="text/javascript" >
var onOff=false;
var replyText='';
window.onload=mainF;
function hideRedNotif()
{
document.getElementById('redNotif').style.display='none';
}
function mainF()
{
fetchNotif();
Updtr=window.setInterval(fetchNotif,25000);
}
function toggleNotif()
{
document.getElementById('redNotif').style.display='none';
if(onOff==false)
{
document.getElementById('parentReply').style.display='';
onOff=true;
}
else
{
document.getElementById('parentReply').style.display='none';
onOff=false;
}
}
function getAjxObject()
{
try {
var o=new XMLHttpRequest();
}
catch(exception)
{
var o=new ActiveXObject('Microsoft.XMLHTTP');
}
return o;
}
function fetchNotif()
{
roundN=document.getElementById('roundName').value;
var o=getAjxObject();
o.open('GET','notifAjx.php?openSes=in&&tru='+roundN,true);
o.onreadystatechange=execute;
o.send();
function execute()
{
if(o.readyState==4 && o.status==200)
{
var countF=0;
resp=o.responseText;
rsp=resp.split('#');
dom=document.getElementById('notifM');
dom.innerHTML=rsp[0];
//document.getElementById('chatRoller').innerHTML=rsp[1];
//if(rsp[1]!=replyText )
//{
//document.getElementById('redNotif').style.display='';
//replyText=rsp[1];
//}
}
}
}
function sendReply()
{
var o2=getAjxObject();
roundN=document.getElementById('roundName').value;
m=document.getElementById('replyText').value;
msg='&&reply=1&&msg='+m;
url='notifAjx.php?tru='+roundN+msg;
o2.open('GET',url,true);
document.getElementById('replyText').value='';
o2.onreadystatechange=execute;
o2.send();
function execute()
{
if(o2.readyState==4 && o2.status==200)
{
}
}
}
</script>
UPDATE- Thanks to everyone for checking my issue, I took screenshots of my DB tables please check if it helps or let me know what else should i provide.
http://i.imgur.com/VJSU2.jpg
http://i.imgur.com/5O6T0.jpg
I will appreciate any suggestion/help.
Thanks & Regards
Prashant
please check for indexing in the table '$moFo'
and check whats the volume of the data you are dealing with, if its high then do archive them or use sharding.
I expect you may have issues because if your asynchronous request takes more than 5 seconds, you'll start to get a backlog. It might sound counter-intuitive, but I recommend making your asynchronous requests a bit more synchronous:
Currently you're using setInterval to run your check every five seconds, regardless of whether a response has come back. What you could do instead is use setTimeout to get it started and then set another timeout when your response has come back, whether it was successful or not. This way, your responses will never start to overlap.
In practice:
Change your mainF() function to be
function mainF()
{
fetchNotif();
Updtr=window.setTimeout(fetchNotif,25000);
}
Then change your fetchNotif() execute() function to set another timeout once it's processed
Updtr=window.setTimeout(fetchNotif,25000);
You may want to wrap that one in an if to check for readyState == 4 but don't check for status == 200 because you probably want it to try again even if the previous attempt failed.

Categories