ERR_INSUFFICIENT_RESOURCES ajax code for REAL-TIME CLOCK - javascript

I created a real-time clock that updates every second. When I run it locally I see no errors. However when I uploaded it to my web host I saw a lot of error messages in the console every time the AJAX code runs.
I think that's the reason why web host suspended my site, telling that my site has performed too many requests.
Here is my code:
$(document).ready(function() {
setInterval(function() {
$('#time').load('timewithdate.php')
}, 1000);
setInterval(function(){
$('#time2').load('time.php')
}, 1000);
})

I'm not sure what kind of answer you are looking for. Your code is a certain way to kill a server: it's making 2 calls to the server every second for each client (read more about DDOS). There is no need to make a server call, just use javascript to get the current time and format it the way you want. You can have something like this:
$(document).ready(function() {
setInterval(function() {
let curTime = new Date();
let date = curTime.toLocaleDateString();
let time = curTime.toLocaleTimeString();
$('#time').text(date + " " + time);
$('#time2').text(time);
}, 1000);
})

The error is because you have effectively DDOS'd your own server with 2 requests every second * number of concurrent clients. I would strongly suggest you remove these AJAX requests and perform the countdown on the client side.
If you're trying to keep the clocks in sync with server time, get the time from the server when the page loads, then add seconds to it on the client side. Do not use AJAX for this, and do not use AJAX polling in future. It's an anti-pattern.

Related

Why does setInterval not increment my clock properly in JavaScript?

I want to display the actual time in New York. I have a html div:
<div id="time"></div>
and also - I have a php script that returns the actual time:
<?php
date_default_timezone_set('UTC');
echo time();
?>
and it does it as a timestamp.
Now, I've created a js script:
var serverTime;
moment.tz.add('America/New_York|EST EDT|50 40|0101|1Lz50 1zb0 Op0');
function fetchTimeFromServer() {
$.ajax({
type: 'GET',
url: 'generalTime.php',
complete: function(resp){
serverTime = resp.responseText;
function updateTimeBasedOnServer(timestamp) { // Take in input the timestamp
var calculatedTime = moment(timestamp).tz("America/New_York");
var dateString = calculatedTime.format('h:mm:ss A');
$('#time').html(dateString + ", ");
};
var timestamp = serverTime*1000;
updateTimeBasedOnServer(timestamp);
setInterval(function () {
timestamp += 1000; // Increment the timestamp at every call.
updateTimeBasedOnServer(timestamp);
}, 1000);
}
})
};
fetchTimeFromServer();
setInterval(function(){
fetchTimeFromServer();
}, 5000);
and the idea behind it is that I want to fetch the data from server, display it on my webpage, then increment it every second for five seconds and then fetch the time from the server again (to keep consistence with time on the server). And later on - continue with doing so, fetching the time, incrementing it for 5 seconds, fetching it again, etc.
It works... almost. After the webpage stays open for some time I can see the actual time, but it 'blinks', and I can see that it shows different times - it's hard to explain, but it looks like there is some time already in that div and new time tries to overlay it for each second. Seems like the previous time (content of this div) is not removed... I don't know how to create a jsfiddle with a call to remote server to fetch time from php, so I only have this information pasted above :(
What might be the problem here?
Since javascript is single threaded, setInterval may not acutally run your function after the delay. It adds the function to the stack to be run as soon as the processor is ready for it. If the processor has other events in the stack, it will take longer than the interval period to run. Multiple intervals or timeouts are all adding calls to the same stack for processing. To address this, you could use HTML5 web workers or try using setTimeout recursively.
Here is a good read on web workers: https://msdn.microsoft.com/en-us/hh549259.aspx

Server saturation with Ajax calls

I'm using PHP over IIS 7.5 on Windows Server 2008.
My web application is requesting repeatedly with Ajax in the background 3 different JSON pages:
page 1 Every 6 seconds
page 2 Every 30 seconds
page 3 Every 60 seconds
They retrieve data related with the current state of some tables. This way I keep the view updated.
Usually I have no much trouble with it, but lately I saw my server saturated with hundreds of unanswered requests and I believe the problem can be due to a delay in one of the request.
If page1, which is being requested every 6 seconds, needs 45 seconds to respond (due to slow database queries or whatever), then it seem to me that the requests start getting piled one after the other.
If I have multiple users connected to the web application at the same time (or with multiple tabs) things can turn bad.
Any suggestion about how to avoid this kind of problem?
I was thinking about using some thing such as ZMQ together with Sockets.io in the client side, but as the data I'm requesting doesn't get fired from any user action, I don't see how this could be triggered from the server side.
I was thinking about using some thing such as ZMQ together with Sockets.io in the client side...
This is almost definitely the best option for long-running requests.
...but as the data I'm requesting doesn't get fired from any user action, I don't see how this could be triggered from the server side.
In this case, the 'user action' in question is connecting to the socket.io server. This cut-down example is taken from one of the socket.io getting started docs:
var io = require('socket.io')(http);
io.on('connection', function(socket) {
console.log('a user connected');
});
When the 'connection' event is fired, you could start listening for messages on your ZMQ message queue. If necessary, you could also start the long-running queries.
I ended up solving the problem following the recommendation of #epascarello and improving it a bit if I get no response in X time.
If the request has not come back, do not send another. But fix the serverside code and speed it up.
Basically I did something like the following:
var ELAPSED_TIME_LIMIT = 5; //5 minutes
var responseAnswered = true;
var prevTime = new Date().getTime();
setInterval(function(){
//if it was answered or more than X m inutes passed since the last call
if(responseAnsswered && elapsedTime() > ELAPSED_TIME_LIMIT){
getData()
updateElapsedTime();
}
}, 6000);
function getData(){
responseAnswered = false;
$.post("http://whatever.com/action.json", function(result){
responseAnswered = true
});
}
//Returns the elapsed time since the last time prevTime was update for the given element.
function elapsedTime(){
var curTime = new Date().getTime();
//time difference between the last scroll and the current one
var timeDiff = curTime - prevTime;
//time in minutes
return (timeDiff / 1000) / 60;
}
//updates the prevTime with the current time
function updateElapsedTime(){
prevTime = new Date().getTime();
}
This is a very bad setup. You should always avoid polling if possible. Instead of sending request every 6 seconds from client to server, send data from server to the clients. You should check at the server side if there is any change in the data, then transfer the data to the clients using websockets. You can use nodejs at the server side to monitor any changes in the data.

Recall Long Polling AJAX Request When it Fails/Network offline

I am implementing a successful long polling within PHP/Node.js application. I have created a routine to launch the long polling AJAX request after the waking up of the computer (after sleep mode) as below.
The problem is that the AJAX request fails due to internet connectivity as it needs some time to get ready and this leads AJAX request to fail. I need to recall this request again until the internet is back but I can't find any way to know if the previous request has failed to send new one and track its status.
I am not using the Jquery and I don't want to use it.
I am able to create a timeout for direct AJAX calls if they don't reach a server within a timeout seconds, but the long polling request status is pending at server for 40 seconds and I need to detect if it fails after 2 seconds from sending.
Is there any solution to do with xmlHTTP object?
I would greatly appreciate your help. Thanks.
var program ={
init: function(){
this.isSleep = function(lastTime){
var lastTime = lastTime;
clearTimeout(program.tt)
program.tt = setTimeout(function(){
var currentTime = new Date().getTime();
if(currentTime > (lastTime + 2000*2) ){
// request fails if the internet connection was not ready
ajax.call({ // long polling request......});
}
program.isSleep(new Date().getTime());
}, 2000);
};
this.isSleep(new Date().getTime());
}
}
Set a variable to true, then call a timer for 2 seconds. If the ajax returns turn that variable to false, if the timer is fired then check your variable and do whatever you need to do.

Cancel Javascript timeout

I have a long process hosted on a Web Server. The thing is triggered from a Web Page, at the click of a button by a user. Some Javascript polls regularly via Ajax to check if the operation has completed server side. To do this, I use setInterval, and later on clearInterval to stop polling.
If this takes too long (e.g. server has crashed), I'd like the client to be informed by some sort of timeout. I've done some research and found about setTimeout. Problem is, if the operation finishes successfully before the timeout, I'd like to cancel this one.
How to do this ?
Would you suggest a different approach ?
PS : I'm targetting IE7/IE8 in particular, but always open to some JQuery
As long as you store your interval's id in a variable, you can use it to clear the interval at any time.
var interval = window.setInterval(yourFunction, 10000);
...elsewhere...
window.clearTimeout(interval);
For more information see the Mozilla Documentation's setInterval example.
Put together a quick JS Fiddle containing a modified version of Mozilla's Example.
To clear a setTimeout, use clearTimeout.
You want two timers (as you said)
repeating interval to do the next poll and
one-time expiration to give up if the server never responds
If the polling is successful you want to clear both the polling interval and cancel the failure timer. If the expiration timer fires you want to clear the polling interval
var checkCount = 0;
function checkComplete() {
console.log("test " + checkCount);
if (checkCount++ > 10) {
console.log("clearing timeout");
window.clearInterval(pollInterval);
window.clearTimeout(expireTimer);
}
}
function cancelPolling(timer) {
console.log("clearing poll interval");
window.clearInterval(pollInterval);
}
var pollInterval = window.setInterval(checkComplete, 500);
var expireTimer = window.setTimeout(cancelPolling, 10000);
You can fiddle with the checkCount constant "10" - keep it low to simulate polling success, raise it higher for the timeout to occur before the checkCount is reached, simulating polling failure.

How to have a timer which cannot be modified in javascript?

Basically, I am designing a quiz application with limited time. Use selects answer to a question and the next question loads using an Ajax request. All questions must be answered within a time frame of, say 2 minutes.
A clock ticks away to show how much time is left and as soon as it hits 0, results are shown. Now since the timer will be implemented using window.setTimeout(), it is possible that the value of timer variable be modified using an external bookmarklet or something like that. Anyway I can prevent this? I think this is implemented on file sharing sites like megaupload. Any forgery on the timer variable results in request for file being rejected.
Have .setTimeout() call an AJAX method on your server to synch time. Don't rely on the client time. You could also store the start time on the server for a quiz, and then check the end time when the quiz is posted.
You need to add a validation in your server side. When the client want to load the next question using an Ajax request, check whether deadline arrived.
The timer in client side js just a presention layer.
If the function runs as a immediately called function expression, then there are no global variables and nothing for a local script to subvert. Of course there's nothing to stop a user from reading your code and formulating a spoof, but anything to do with javascript is open to such attacks.
As others have said, use the server to validate requests based on the clock, do not rely on it to guarantee anything. Here's a simple count down that works from a start time so attempts to dealy execution won't work. There are no global variables to reset or modify either.
e.g.
(function (){
// Place to write count down
var el = document.getElementById('secondsLeft');
var starttime,
timeout,
limit = 20; // Timelimit in seconds
// Function to run about every second
function nextTick() {
var d = new Date();
// Set start time the first time
if (!starttime) starttime = d.getTime();
var diff = d.getTime() - starttime;
// Only run for period
if (diff < (limit * 1000)) {
el.innerHTML = limit - (diff/1000 | 0);
} else {
// Time's up
el.innerHTML = 0;
clearTimeout(timeout);
}
}
// Kick it off
timeout = window.setInterval(nextTick, 1000);
}());

Categories

Resources