Ajax/PHP long-polling results in 503 error - php

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.

Related

ajax firing multiple times after database becomes unlocked

I'm having a problem with an ajax call.
I have some code set up to run a function every 2 seconds which looks to see if the content has been updated or not with WordPress ajax, does some work with php, then updates a database:
window.setInterval( "updateContent()", 2000 );
function updateContent(){
if($('#needcontent').hasClass('yes')){
CONTENT.updateContent( 'monitor' , ids );
}
}
$(function() {
CONTENT= {
updateContent: function(callback, data){
data = {
action: 'myplugin_do_ajax',
callback: callback,
data: data
};
$.post(ajaxurl, data, function(response){
switch(data.callback){
case 'monitor' :
data_returned = eval("(" + response + ")");
if(data_returned.completed == 'true'){
//Adjust the DOM because there was a content update, and remove the class "yes" from #needcontent to stop the check until next time
}
else{
//Do nothing because no content was found, let the Interval run again
}
break;
}
}
}
}
The problem I'm finding is that sometimes the content is quite large, and ends up locking the table while php updates the database. The ajax call runs once, runs into a database lock, and doens't return anything until the database is unlocked again. The database could be locked for a 10 second period, resulting in 1 run and 4 not-run calls.
UPDATE:
It's not the database locking, it's the php function taking longer than 2 seconds to return, causing the Interval to loop again and again without a response.
What's happening is those 4 not-run ajax calls then begin to fire one right after the other like they are trying to catch up or something.
I've tried increasing the Interval time to 10 seconds, but that doesn't solve the problem because if the database is locked for 11 seconds it'll still fire twice.
I've tried using global variables in Javascript (yuck) to stop the Interval from calling the function, but that doesn't seem to work either.
UPDATE 2:
I answered my own question below to what worked for me.
try this:
window.updateCheck= window.setInterval( "updateContent()", 2000 );
function updateContent(){
if($('#needcontent').hasClass('yes')){
CONTENT.updateContent( 'monitor' , ids );
clearInterval(window.updateCheck);
}
}
$(function() {
CONTENT= {
updateContent: function(callback, data){
data = {
action: 'myplugin_do_ajax',
callback: callback,
data: data
};
if(window.ajaxCall) window.ajaxCall.abort();
window.ajaxCall= $.post(ajaxurl, data, function(response){
window.updateCheck= window.setInterval( "updateContent()", 2000 );
switch(data.callback){
case 'monitor' :
data_returned = eval("(" + response + ")");
if(data_returned.completed == 'true'){
//Adjust the DOM because there was a content update, and remove the class "yes" from #needcontent to stop the check until next time
}
else{
//Do nothing because no content was found, let the Interval run again
}
break;
}
}
}
}
what we did here was to put the interval in a global variable, and also the ajax call ($.post() call actually), then when the conditions of updating is checked, we stop the interval, kill all the other active or queued request and send the ajax request to the server.
while the request is being sent to the server the update checks are stopped, then as soon as the server responds to the request we start the update check again!
charlietfl's comment on my OP got me thinking about the difference between setInterval and setTimeout, and I realized that:
a) setInterval would continuously run, regardless if a result is returned or not. In my case, using ajax, the function was being call asynchronously so the setInterval wouldn't care if a result was returned.
b) If I changed the code to use setTimeout, I could control the outcome more.
This is what I did.
Firstly, remove the setInterval function completely, it's not needed.
Then I changed my switch case to this:
case 'monitor' :
var monitor = false;
data_returned = eval("(" + response + ")");
if(data_returned.completed == 'true'){
//Adjust the DOM because there was a content update, and remove the class "yes" from #needcontent to stop the check until next time
}
else{
//Run the monitor after a 2 second timeout.
var ids = j('.contentDiv').attr('id');
window.setTimeout(CONTENT.updateContent( 'monitor' , ids ) , 2000);
}
break;

Sending data from server to client?

I have a php server file and an HTML client file, the HTML file send ajax requests to the server to retrieve data every 500 ms, this although works as expected it's causing high usage of memory and CPU on the client's device.
PHP
if(isset($_POST['id']) && $_POST['id'] != '' )
{
$id = $_POST['id'];
$select = $con->prepare("SELECT * FROM data WHERE id=?");
$select->bind_param('s', $id);
$select->execute();
$result = $select->get_result();
while($row = $result->fetch_assoc())
{
echo $row['column 1'] . "\t" . $row['column 2'] . "\n";
}
}
AJAX
function send(){
var formdata = new FormData(),
id = document.getElementById('id').value;
formdata.append('id', id);
var xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('post', 'server.php', true);
xhr.send(formdata);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText);
}
}
}
setInterval(function(){send()}, 500);
I would like to find an alternative solution to ajax, instead of sending numerous requests to the server and retrieving same data most of the time, it would be much more efficient if the server can interact with the client on data change or update.
I can't use PHP Socket or HttpRequest methods as they are not installed on my hosting server and I'm not sure if the later works. The only way I can think of is using SESSIONS.
According to this PHP server store all users sessions on the same directory on the server, therefore it may be possible to change sessions variables for a particular user directly on the file. The problem however is the data in those files are serialized and I'm not sure how to de-serialize the data and re-serialize them and then save the new data!
Even if I was able to find a way to store updates on the session file, I still need to use setInterval to listen to the session's variable change every 500ms although it's not ideal but it would be much better than using XMLHttpRequest in terms of memory and CPU usage.
So what's the best way to do this? any help would be much appreciated.
UPDATE:
I realized that SESSION wont work because it can be read only by the server not the client, therefore i have to send ajax request to the server to get the variables which i was trying to avoid.
I tried long polling but i had many problems with it, flush and ob_flush() doesn't work on my server and i can't change the ini settings. When trying the infinite loop i can't get it to break on data change:
if(isset($_GET['size']) && $_GET['size'] != '')
{
$size = (int)$_GET['size'];
$txt = "logs/logs.txt";
$newsize = (int)filesize($txt);
while(true) {
if($newsize !== $size) {
$data = array( "size" => filesize($txt), "content" => file_get_contents($txt));
echo json_encode($data);
break;
}
else{
$newsize = (int)filesize($txt);
usleep(400000);
}
}
}
it keeps going on and on, even if the logs.txt size increase it won't break! how can I make it break and echo data on size increase?
UPDATE 2:
It turned out the php cache the filesize when calling filesize() method therefore the above loop will run indefinitely, the solution for that is to use clearstatcache() method which will clear the stored cache of the file size allowing the loop to break on filesize changes.
Okay, after many tests and long research i came to the conclusion that PHP server can never interact with a specified client directly unless the client send a request to the server first.
The only reliable solution i found is to use infinite loop which will only break on data change, this will reduce the frequency of ajax requests to the server considerably, hence increasing the performance and decreasing the usage of the Memory and CPU on the client's device, here how it goes:
PHP 1 (Handles data update or new data insert to database):
$process = $_POST['process'];
$log = "/logs/logs.txt";
if($process == 'update'){
//execute mysqli update command and update table.
$str = "Update on " . date('d/m/Y - H:i:s') . "\n";//add some text to the logs file (can be anything just to increase the logs.text size)
file_put_content($log, $str, FILE_APPEND);//FILE_APPEND add string to the end of the file instead or replacing it's content
}
else if($process == 'insert'){
//execute mysqli insert command and add new data to table.
$str = "Added new data on" . date('d/m/Y - H:i:s') . "\n";
file_put_content($log, $str, FILE_APPEND);
}
The above code will insert/update data, create file log.txt if not existed and add additional text to it on each request. log.txt will be used later in the infinite loop "below" and would break the loop when it's size change.
PHP 2 (handles reading data requests):
if(isset($_POST['id']) && $_POST['id'] != '' && isset($_POST['size']) && $_POST['size'] != '')
{
$id = (string)$_POST['id'];
$init_size = (int)$_POST['count'];
$size = file_exists('logs/logs.txt') ? (int)filesize('logs/logs.txt') : 0;//$size is logs.txt size or 0 if logs.txt doesn't exist(not created yet).
$select = $con->prepare("SELECT * FROM data WHERE id=?");
$select->bind_param('s', $id);
while(true){ //while(true) will loop indefinitely because condition true is always met
if($init_size !== $size){
$select->execute();
$result = $select->get_result();
while($row = $result->fetch_assoc())
{
$data['rows'][] = array(
"column 1" => $row['column 1'],
"column 2" => $row['column 2'],
);
}
$data['size'] = $size;
echo json_encode($data);
break; //break the loop when condition ($init_size != $size) is met which indicates that database has been updated or new data has been added to it.
}
else{
clearstatcache(); //clears the chached filesize of log.txt
$size = file_exists('logs/logs.txt') ? (int)filesize('logs/logs.txt') : 0;
usleep(100000) //sleep for 100 ms
}
}
}
AJAX:
var size = 0; //declares global variable size and set it's initial value to 0
function send(s){
var formdata = new FormData(),
id = document.getElementById('id').value;
formdata.append('id', id);
formdata.append('size', s);
var xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('post', 'server.php', true);
xhr.timeout = 25000; //set timeout on xmlhttprequest to 25 sec, some servers has short execution tiemout, in my case it's 27 sec so i set the value to 25 sec.
xhr.send(formdata);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
var data = JSON.parse(xhr.responseText);
size = data.size;
console.log(data.rows);
setTimeout(function(){send(size)}, 100); //re-initiate the request after receiving data
}
}
xhr.ontimeout = function(){
xhr.abort(); //abort the timed out xmlhttp request
setTimeout(function(){send(size)}, 100);
}
send(size);
This is not the ideal solution but it reduced my xmlhttp requests from 2/sec to as low as 1/25 sec, hope that someone will be able to come up with a better solution.
Before we had capabilities to use sockets in browsers, we used Long polling. The basic idea is that instead of the browser making requests at regular intervals, the browser will make a request to the server, but the server won't respond until there is something worthwhile to share back to the browser. That means the request could be left open for 10ms or for hours.
After the server responds with something, it is then the browser's job to make a new ajax request. This way, there is always a line open to the server.
Refer to this question for more information.
Answering the part of your question about directly editing a session...
To directly manipulate the session of a user, I will assume you know and can track any user's session ID (perhaps in your database on sign in).
When you need to edit a user's session directly on the server:
Retrieve user's last known session from the database.
Call session_close() to close the current session (if there is one).
Call `session_name($sessionId)' with the session ID.
Call session_open() to open that session. $_SESSION should be populated with the session data. You will not need to unserialize anything.
Make your edits to the session.
Call session_close() to reserialize the data.
Alternatively, you could directly open the session file, unserialize() it, edit the data, and re-serialize() manually.
You could create an ajax request to an php script which will only return data if there is any new data. As long there is no new data the script keeps running in a loop until there is.
I think the anwser for this question today is to use Websocket read about it. without request the server you can get data if there's something change it into server
see link
you can use SSE or Websocket to achieve this.

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

Checking multiple fields from mysql with jquery AJAX in one call

I've got a page that seems to be in full working order, but I'm having major performance issues (think 30 second delay occasionally from these calls) from what I assume is throwing too many individual POST requests to the server.
Am I right in thinking that there's some way of doing it all in one call and that doing so would improve performance, and what's the easiest way of doing it? Perhaps my use of eval() is part of the problem - or maybe my webhost is just shit.
function startCheckAchs(){
//hide the loading alert
$(document).ajaxStop(function(){
$(this).unbind("ajaxStop");
popup('loadingAlert');
});
//load lifeTimeBaked
lifeTimeBaked = loadAch("lifetimebaked");
loadAch("ach_started", "#achStarted", "achstarted");
loadAch("ach_round1", "#achRound1", "achround1");
loadAch("ach_round2", "#achRound2", "achround2");
loadAch("ach_round3", "#achRound3", "achround3");
if( rewards == 1) {
loadAch("ach_baked100", "#achBaked100", "achbaked100");
loadAch("ach_baked500", "#achBaked500", "achbaked500");
loadAch("ach_baked1000", "#achBaked1000", "achbaked1000");
loadAch("ach_nobread", "#achNoBread", "achnobread");
loadAch("ach_nodough", "#achNoDough", "achnodough");
loadAch("ach_noflour", "#achNoFlour", "achnoflour");
loadAch("ach_allach", "#achAllAch", "achallach");
}
}
function loadAch(ach, achDiv, achVar){
$.ajax({
type: "POST",
url: "scripts/loadach.php",
data: {"achievement" : ach},
dataType: "text",
success: function(result){
if ( achDiv && achVar && result == 1){
$(achDiv).show();
eval(achVar + " = 1");
return result;
} else {
return result;
}
}
});
}
Loadach.php:
$achievement=trim($_POST['achievement']);
$user = $_SESSION['userid'];
$query = "SELECT $achievement FROM breadusers WHERE userid='$user'";
$link =#mysql_query($query);
if(!$link){
die('Could not query:' . mysql_error());
}
echo mysql_result($link, 0);
?>
You are currently loading achievements individually, while you should be doing something like:
<?php
$query = "SELECT ach_started, ach_round1 FROM breadusers WHERE userid='$user'";
$link = mysql_query($query);
$results = mysql_fetch_assoc($link);
echo json_encode($results);
?>
Then, in your javascript code, parse the JSON response (setting dataType: "json" should work), loop over the returned object (has keys such as ach_started, ach_round1, etc etc), and show/hide divs as needed.
Unfortunately you are going to have to redesign that.
SQL queries are slow.
Lots of requests make things slow.
See if you can group all of the data for a user in your database. That way you can make one select for all of the data you need.
You could use a multi-dimensional array and fill it with the data needed, send the array with ajax to the php code, and then you could loop through the array in the php code and echo back the desired results.
This way you would only be making 1 ajax call each time but still get the same results. might be faster this way but i have not tested this. =)
Most browsers have a limit on the number of concurrent server requests they can handle.
If you're using sessions, you'll also find that the server can only process a single request for each session at a time, because the session file is locked by each request, and subsequent requests must wait for it to be unlocked either when the first request finishes, or when a session_write_close() is issued by the executing request.

Categories