getting connection reset after sending a jquery ajax $.post - javascript

I am making a game lobby with php, jquery, ajax.
I have php echo a string that is a jquery loop that sends ajax $.post's to another page to check and see if some one joined the players game, if new users are online and to get current games to join. if there is then I fill div's on the page with the new data.
here is the loop
<script>
$(function() {
getPage = function() {
// this gets all current games users are trying to start up
$.post("lobbyClasses.php",
{
lobbyRequest: "getGames",
},
function(data, status){
if(status == "success"){
$("#joinGameContainer").html(data);
// this gets all online users and puts themin a div onlineUsers
$.post("lobbyClasses.php",
{
lobbyRequest: "getOnlineUsers",
},
function(data, status){
if(status == "success"){
$("#onlineUsers").html(data);
// start it again;
setTimeout(function(){
getPage();
}, 5000);
}else{
// get all online users failed start loop again
$("#onlineUsers").html("failed...");
setTimeout(function(){
getPage();
}, 5000);
}
});
}else{
//get all games failed start loop again
$("#joinGameContainer").html("failed...");
setTimeout(function(){
getPage();
}, 5000);
}
});
}
getPage();
});
</script>
The problem is that this loop only works sometimes and others the browser(chrome and firefox) will stall and give an error (connection reset in firefox)(no data returned in chrome) I thought that nesting the post request might help and it did significantly but it still happens from time to time. It also happens a lot more when i send another post to a different page such as the following ....
$("#makeGame").click(function(){
getGame = function() {
$("#scripts").html("getting data...");
$("#onlineUsers").html("getting data...");
$("#joinGameContainer").html("getting data...");
$("#gameContainer").html("getting data...");
//alert("newgame was clicked.");
$.post("cardgameclasses.php",
{
gameRequest: "makeGame",
},
function(data, status){
// the code stalls here and dose nothing then the browser error happens
//alert("Data: " + data + "\nStatus: " + status);
if(status == "success"){
$("#scripts").html(data);
}else{
$("#scripts").html("failed...");
setTimeout(function(){
getGame();
}, 5000);
}
});
}
getGame();
so I thought that replacing the loop with text then sending the post would help and it did a little bit but on occasion i still get a browser error connection reset. i am not sure what i am doing wrong please help.

I figured out what was going on with my code PHP only allows so many post vars to a single page to prevent denial of service attacks. I was sending too many posts. I also realized that every thing I was trying to update with ajax could be updated with a single post instead of 4 nested posts. The processing of the data can be done on server side. If you are making several posts for one page you are doing something wrong. The proper code would be this:
function myTimer() {
$.post("lobbyClasses.php",
{
lobbyRequest: "getContent1",
},
function(data, status){
if(status == "success"){
$("#lobbyContent").html(data);
}else{
$("#lobbyContent").html("failed...");
}
});
}
myTimer();
var myVar = setInterval(function(){ myTimer() }, 5000);
function myStopFunction() {
clearInterval(myVar);
}

var newarray = [];
var dateandtime = Date.now();
newarray.push(dateandtime);
function myTimer() {
if( newarray[0] + 1000 < Date.now()){
$.post("lobbyClasses.php",
{
lobbyRequest: "getContent1",
},
function(data, status){
if(status == "success"){
$("#lobbyContent").html(data);
}else{
$("#lobbyContent").html("failed...");
}
});
newarray[0] = Date.now();
}
}
myTimer();
var myVar = setInterval(function(){ myTimer() }, 5000);
function myStopFunction() {
clearInterval(myVar);
}

Related

How to make page reload after 2 seconds if an "else" statement happens in javascript

So if i fail to login or user does not appear it will prompt a message failed to login or user not found and when that happens i wish the page to reload and go back to the login screen again, i tried with set timeout function but it does not seem to work. Thanks in advance
if (error) {
respond.json(error);
} else {
// If user can be found, result has one record
if (result.length > 0) {
if (input_password == result[0].user_password) {
msg = "1"; // "Success!";
console.log(msg);
} else {
msg = "Login Fail!";
console.log(msg);
}
} else { // If user not found, result has no record
setTimeout(function(){
msg = "User not found!";
window.location.reload(1);
}, 2000);
}
Try just using window.location.reload(true);
It sounds like you need a reference to this.
Why can't I pass "window.location.reload" as an argument to setTimeout?
So before you make the setTimeout save the reload function so it has the proper this.
var fun = window.location.reload(true);
setTimeout(function(){
msg = "User not found!";
fun();
}, 2000);
So Bind it to

Best way to request data from server every x seconds

I created a very simple example. I try to request a value from my server every X seconds, in this case i simply want to get a random number, every second.
This solution works, but unfortunately there seems that an infinite loop occurs after a while, which leads to a crash. I also get over 100k Errors after a while net::ERR_INSUFFICIENT_RESOURCES.
request_data(1000);
function request_data(intervall) {
$.post('ajax.php', {
cmd: "get_random_number"
}, function (returned_data, status) {
if (status === "success") {
$("#result_output").html(returned_data);
setInterval(function() {
request_data(intervall);
}, intervall);
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="result_output></p>
// ajax.php
<?php
$cmd = filter_input(INPUT_POST, "cmd");
if (isset($cmd) && $cmd == "get_random_number") {
echo rand(5, 15);
}
Whats the best solution to achieve this?
You could do a setInterval, and then inside this do an ajax call. One of the parameters you can set in the $.ajax is a timeout - so that you can stop multiple ajax calls stacking up and causing problems.
$.ajax({
url: '',
type: '',
data: {},
timeout: 3000,
success: function(data){
// do stuff
}
});
For more info on the parameters, see http://api.jquery.com/jQuery.ajax/
As Derek has pointed out, this is because, you are making 2^n calls since the setInterval is inside the function itself.
Try it like this instead
window.setInterval(1000, request_data);
function request_data() {
$.post('ajax.php', {
cmd: "get_random_number"
}, function (returned_data, status) {
if (status === "success") {
$("#result_output").html(returned_data);
}
});
}
I solved it by simply replacing setInterval with setTimeout.

How to use mouse event to do AJAX call only if user is idle for X seconds

Apologies if this is a repost. I have seen many examples. But I can't seem to put together my needs.
I have a "today" page which displays all groups. Throughout the day more and more groups will appear. I want to be able to dynamically update these groups if the user has the page open and hasn't moved the mouse for X seconds. I have this chunk of code:
var timeout = null;
j$(document).on('mousemove', function() {
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
timeout = null;
//calls another page to check if there's new data to display. if so, wipe existing data and update
j$.ajax({
url: "/include/new_Groups.php",
cache: false,
success: function(data){
j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
}
})
.done(function( html ) {
});
}, 3000);
});
What this is doing is if the user hasn't moved the mouse after 3 seconds, do an AJAX call to update the group. This semi works. If you don't move the mouse, it will update. But it won't update again unless the mouse is moved and idle again for 3 seconds which is not good user experience.
I'm trying to find a way to just continually update the page every 3 seconds (for this example) if the user is idle. But if he's moving the mouse, there is to be no updating. Please ask questions if I'm unclear! Thanks in advance.
Should be straigh forward, use an interval and a function call instead
jQuery(function($) {
var timer;
$(window).on('mousemove', function() {
clearInterval(timer);
timer = setInterval(update, 3000);
}).trigger('mousemove');
function update() {
$.ajax({
url : "/include/new_Groups.php",
}).done(function (html) {
$(".group_Container_Main").append(html).fadeIn('slow')
});
}
});
FIDDLE
EDIT:
To solve the issue of stacking ajax requests if for some reason they take more than three seconds to complete, we can just check the state of the previous ajax call before starting a new one, if the state is pending it's still running.
jQuery(function($) {
var timer, xhr;
$(window).on('mousemove', function() {
clearInterval(timer);
timer = setInterval(update, 1000);
}).trigger('mousemove');
function update() {
if ( ! (xhr && xhr.state && xhr.state == 'pending' ) ) {
xhr = $.ajax({
url : "/include/new_Groups.php",
}).done(function (html) {
$(".group_Container_Main").append(data).fadeIn('slow')
});
}
}
});
On the AJAX parameter, use the complete option to trigger a mouse move :
j$(document).on('mousemove', function() {
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
timeout = null;
//calls another page to check if there's new data to display. if so, wipe existing data and update
j$.ajax({
url: "/include/new_Groups.php",
cache: false,
success: function(data){
j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
},
complete: function(data){
j$(document).trigger('mousemove');
}
})
.done(function( html ) {
});
}, 3000);
});
You can invert your timer idea to this logical connection...
Set a timer for 3 seconds after which you will do the AJAX call
If the mouse is moved, reset the timer for 3 seconds
You now have a three second timer running whether or not the mouse is moved and you reset it on mouse move to get the behaviour you want in respect of only updating on idle.
var timeout = setTimeout(update, 3000);
function update() {
clearTimeout(timeout);
//calls another page to check if there's new data to display. if so, wipe existing data and update
j$.ajax({
url: "/include/new_Groups.php",
cache: false,
success: function(data){
j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
}
}).done(function(html) {
}).always(function() {
timeout = setTimeout(update, 3000);
});
}
j$(document).on('mousemove', function() {
clearTimeout(timeout);
timeout = setTimeout(update, 3000);
});
You should use setInterval() instead of setTimeout() to make a repeating event.
I would call setInterval() outside of your event handler code, and then make your event handler code update a lastTimeMouseMoved (or something) timestamp, which would be checked by the code passed to your setInterval() call.
So, your code might look like this:
const IDLE_TIME = 3000;
var lastTimeMouseMoved = Date.now();
timer = setInterval(function() {
if(Date.now() - lastTimeMouseMoved >= IDLE_TIME) {
//calls another page to check if there's new data to display. if so, wipe existing data and update
j$.ajax({
url: "/include/new_Groups.php",
cache: false,
success: function(data){
j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
}
})
.done(function( html ) { });
} // end idle if
}, IDLE_TIME);
j$(document).on('mousemove', function() {
lastTimeMouseMoved = Date.now();
});

Preventing error 503 on JQuery load

This is my code on shoutbox update :
function updateShoutbox(){
$("#shoutdiv").load("shoutbox.php", { 'action': 'update' } ,
function (responseText, textStatus, req) {
if (textStatus == "error") {
return false;
}
});
}
$(document).ready(function(){
updateShoutbox();
var auto_refresh = setInterval(
function ()
{
updateShoutbox();
$("#shoutdiv").scrollTop($("#shoutdiv")[0].scrollHeight);
}, 6000);
It returns error each some minutes :
shoutbox.php returned error:
Service Unavailable
Is there anyway to handle this error and hide it somehow ?
I edited my code so to stop showing any error on shoutbox update, but it still shows this error each minutes.
Ok, so let's take this for example:
$(document).ready(function(){
(function iterate(i) {
if (!!i) {
console.log('iteration #', i--);
setTimeout(function next(){
iterate(i);
}, 1000);
}
})(10);
});​
http://jsfiddle.net/userdude/6C8yp/
If you look at the console, you'll see it counts down until i is equal to 0, or i is not given (that's what the !! is for there). What I'm doing here is looping each second, but only after the last loop has finished. I'm feeding my loop.
Looking at what you have here, I might do this instead:
$(document).ready(function($){
var $shoutbox = $("#shoutdiv"),
timer;
(function update(){
var opts = {
url: 'shoutbox.php',
action: 'update',
complete: wait
};
$.ajax(opts);
function wait(res, status, req){
if (status == 200) {
$shoutbox
.append(res)
.scrollTop($shoutbox[0].scrollHeight);
timer = setTimeout(update, 6000);
}
}
})();
});​
http://jsfiddle.net/userdude/whsPn/
http://jsfiddle.net/userdude/whsPn/1/
Ok, so what we have above should mostly emulate the code you have in the question. You'll note that I have the complete: wait part in there, and the setTimeout() is in that callback. And.. it's only called if the status returned is 200 (success).
Now, there you could turn complete: wait to success: wait, and take out the status == 200 if statement altogether. Of course, if you do want to run the update again, but maybe do something different, this is your chance.
Also note, in the fiddle linked I've got some dummy code in there. So don't just copy/page what's in the fiddle, or you'll have errors and it won't run at all.
EDIT: Oops, found an error with url =. Fixed.
If you want to "hide" your error instead of looking for the cause of the error in the first place, try this in your callback function in the $.load:
function (responseText, textStatus, req) {
if(req.status!=200&&req.status!=302) {
return false;
}
//update the shoutbox
}
At least to me this is what seems to be the most reliable way to prevent random errors from getting through your checks.

XMLHttpRequest leak

Below is my javascript code snippet. Its not running as expected, please help me with this.
<script type="text/javascript">
function getCurrentLocation() {
console.log("inside location");
navigator.geolocation.getCurrentPosition(function(position) {
insert_coord(new google.maps.LatLng(position.coords.latitude,position.coords.longitude));
});
}
function insert_coord(loc) {
var request = new XMLHttpRequest();
request.open("POST","start.php",true);
request.onreadystatechange = function() {
callback(request);
};
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
request.send("lat=" + encodeURIComponent(loc.lat()) + "&lng=" + encodeURIComponent(loc.lng()));
return request;
}
function callback(req) {
console.log("inside callback");
if(req.readyState == 4)
if(req.status == 200) {
document.getElementById("scratch").innerHTML = "callback success";
//window.setTimeout("getCurrentLocation()",5000);
setTimeout(getCurrentLocation,5000);
}
}
getCurrentLocation(); //called on body load
</script>
What i'm trying to achieve is to send my current location to the php page every 5 seconds or so. i can see few of the coordinates in my database but after sometime it gets weird. Firebug show very weird logs like simultaneous POST's at irregular intervals.
Here's the firebug screenshot:
IS there a leak in the program. please help.
EDIT: The expected outcome in the firebug console should be like this :-
inside location
POST ....
inside callback
/* 5 secs later */
inside location
POST ...
inside callback
/* keep repeating */
Probably not the problem, but I can suggest two refactorings:
Merge your two conditions in callback():
if ((req.readyState == 4) && (req.status == 200)) {
And you can shorten your setTimeout line to:
setTimeout(getCurrentLocation, 5000);
And in an effort to fix the problem, can I get you to remove the setTimeout() from callback(), and replace the call to getCurrentLocation() with it? So you're only writing "callback success" when the callback is run, nothing else.
setTimeout(getCurrentLocation, 5000); //called on body load

Categories