I want to run a counter on the back end of a website, so that it is constantly counting. I made a javascript counter (http://directinvent.com/counter/) which displays the desired result, although this resets whenever the site is loaded for each individual user.
The idea is simple enough. Run the counter back end and display the result live on front end. Any ideas on how this can be done?
The same way you would do a Timer in Javascript. You store when you start your counter. Then you recalulate the result on every update (request). No need to do the math every 1/10s. If nobody ask, this is useless.
Basicly, this will look like this :
long startTime = storeTimeFor(User);
return (currentTimeInSec - startTimeInSec) * incrementationPerSec
With this, you only need to store the startTime for each user (in database, file, or in cache if you want). On reset, just store the currentTime again.
This is how you would do a timer in lots of langage because incrementing a value every seconds (using a sleep(1000)) would not be precise since your thread will not be running all the time, your are not alone on the machine ;)
EDIT :
On the client side, I would not call to much the server, just ask the value store and do the math from the client with the same logic. Using a timeout to do the math over and over every X ms. See how to create a timer in Javascript if need, only the value calculate would change here.
The counter must be stored in the backend (in file or database), either it is a single counter or one counter per user.
When rendering the page, initially show the counter that is read from the backend.
If the speed of the counter is known and constant (e.g. increase 3 per second), then you can use javascript (setTimeout) to increase it every second. The backend will store a number and the time (unix time) when it was created, e.g. 120 at 08:00:00. If a user access the website at 09:00:15, you know that it is 3615 seconds later, so you render the initial page showing the starting counter as 120 + (3615/3) = 1325. After that, the javascript will increment and display it by 3 per second.
If the speed of the counter is unknown, then you need to periodically (e.g. once per 10 seconds) check to the backend via ajax, requesting the current value of the counter. You can immediatelly display that latest value (which means the counter will be updated once every 10 seconds). Or, if you want to give a sense of "live", you can display it incrementally with animation on the client side.
Example: current display shows 120. Ten seconds later, via ajax request you get a new value 150. The difference is 150-120 = 30 in 10 seconds. You can display the counter increased by 3 per second (120, 123, 126, 129, 132, 135, 138, 141, 144, 147, 150). You can also play with random increment to be more realistic, as long as the total increment is 30 in 10 seconds.
I solved this simply by getting the time of the day with the Date() variable, and multiplying the time of the day by the incremental constant desired. This way the scheme will automatically update every day with the correct number as wanted and all the users will be displayed the correct number at any given time.
function dotimer()
{
today=new Date()
window.setInterval("dotimer()",speed)
testMilli = today.getMilliseconds()
testSeconds = today.getSeconds()
testMinutes = today.getMinutes()
testHours = today.getHours()
totalCost = Math.round(testHours * 10800 + testMinutes * 180 + testSeconds * 3 + testMilli * 0.003);
document.getElementById("counterSeconds").innerHTML = totalCost;
}
Although this works for this purpose, it still manages to freeze the browser, so I will have to work out a way to handle this...
Related
I have a timer countdown with javascript.It countdowns from 3 minutes.But if user reloads the page I have to resume the countdown.I mean user loaded the page and countdown starts from 3 minutes then after 1 minute user reloads the page countdown should start from 2 minutes.How can I do this ? I don't want any code I need the algorithm.
After each second change, you need to save the state of the counter into some kind of persistent storage.
I'd just use:
localStorage['time_left'] = JSON.stringify(time_left);
When you load the page, first you try to load the state of the timer.
time_left = JSON.parse(localStorage['time_left']);
And then check whether the value was even stored.
if(time_left===undefined){// you're on fresh instance
Would also be good idea to clear the stored variable after the timer finishes.
Good luck :>
You need to persist the current time left to the end of the timer somewhere where you can access it later, even after the page has been refreshed. Local storage comes to mind, but other methods may be possible.
Instead of setting the timer to 3 minutes, you set an interval to run a function every second. You save two pieces of information to your storage:
Amount of time till the end, perhaps in seconds ( 180s for 3 minutes)
Amount of time already passed since the start (0 by default, incremented with each interval)
Every time the interval function ticks, you increase the total time passed and check if it is already higher than the total amount expected. Do your custom actions when the condition is true. Do not forget to clear the interval, otherwise it will keep going on indefinitely and uselessly.
var remaining = localStorage.remaining || 180;
window.setInterval(function(){
remaining = remaining - 1;
document.querySelector('#countdown').innerHTML = remaining;
}, 1000);
window.onbeforeunload = function(){
// Save remaining time as the window is closed or navigated elsewhere
localStorage.remaining = remaining;
};
I want to develop a script, which will reduce a numeric value -3 once a day, this script is for my store
<script type="text/javascript">
$(document).ready(function() {
var store_count = 952;
var Date_val = new Date();
//Daily once I need to reduce my store_count -3
if(Date_val == 'Here i have to check the condition for allowing this happen daily once') {
store_count = store_count-3;
$('#deducted_store_count').text(store_count);
}
});
</script>
<div id="deducted_store_count">952</div>
I am not storing this value in Database. Just I want to place this value in a div. As like I mentioned above.
I don't want to subtract the date as someone has flagged this question for subtraction of date, my question is different.
if my store count is 952 today, tomorrow it have to reduce to 949 and -3 for a each and every day.
OK. I'm going to tell you how, then I'm going to question very hard, "Why?"
Here's how:
var store_count = 952;
// 24 hours, 60 minutes per hour, 60 seconds per minute, 1000 milliseconds per second
var delay = 24 * 60 * 60 * 1000;
window.setInterval(
function () {
store_count = store_count - 3;
$('#deducted_store_count').text(store_count);
}, delay);
So here's my question, what are you thinking you're accomplishing here? Going down three per day, the store count would finally be down to zero after 317 days. How is this program going to run in any browser or Node.js server with an in-memory variable like store_count undisturbed for that length of time without any chance of a power outage or somebody closing down the software?
Data which is slowly going to be decremented or otherwise manipulated over a long period (anything over a few minutes) is usually stored in some kind of long term storage like a database, a file, localStorage in the browser, etc. Something that is persistent and can be guaranteed to still exist if something happens to the environment. But you're asking this question like you think "store_count" is going to be around to celebrate its next birthday.
Are you sure this data shouldn't be in MongoDB or something somewhere?
I have 2 node.js webservers. I cache data inside webservers. I sync the cache load/clear based on system time. I have done time sync of all my hosts.
Now I clear cache every 15 mins using following code:
millisTillNexthour = "Calculate millis remaining until next hour"
setTimeout(function() {
setInterval(function() {
cache.clear();
}, 60000*15);
}, millisTillNexthour);
My expectation is even if this process runs for ever, cache will be cleared every 15th minute of each hour of the day.
My question is: can setInterval drift over time?
For eg: right now it clears cache at 10:00 10:15 10:30 10:45 11:00 ......
Can it happen that instead of 10:15 system time, setInterval gets executed at 10:20 system time when it was supposed to clear cache at 10:15??
I am not sure how this works. Please shed some light. I hope I explained my question well.
I'm probably more than a bit late to the party here, but this is how I solved this particular time-slipping problem just now, using a recursively called setTimeout() function instead of using setInterval().
var interval = 5000;
var adjustedInterval = interval;
var expectedCycleTime = 0;
function runAtInterval(){
// get timestamp at very start of function call
var now = Date.now();
// log with time to show interval
console.log(new Date().toISOString().replace(/T/, ' ').replace(/Z/, '') + " runAtInterval()");
// set next expectedCycleTime and adjustedInterval
if (expectedCycleTime == 0){
expectedCycleTime = now + interval;
}
else {
adjustedInterval = interval - (now - expectedCycleTime);
expectedCycleTime += interval;
}
// function calls itself after delay of adjustedInterval
setTimeout(function () {
runAtInterval();
}, adjustedInterval);
}
On each iteration, the function checks the actual execution time against the previously calculated expected time, and then deducts the difference from 'interval' to produce 'adjustedInterval'. This difference may be positive or negative, and the results show that actual execution times tend to oscillate around the 'true' value +/- ~5ms.
Either way, if you've got a task that is executing once a minute, and you run it for an entire day, using this function you can expect that - for the entire day - every single hour will have had 60 iterations happen. You won't have that occasional hour where you only got 59 results because eventually an entire minute had slipped.
setInterval is definitely drifting (although I agree that it should not be). I'm running a Node.js server with an interval of 30 seconds. On each tick, a few async web requests are made which from beginning to end take roughly 1 second. No other user-level/application processing happens in the intervening 29 seconds.
However, I notice from my server logs that over the course of 30 minutes, a drift of 100ms occurs. Of course, the underlying operating system is not to blame for the drift and it can only be some defect of Node.js's design or implementation.
I am very disappointed to notice that there is a bug in the NodeJS implementation of setInterval. Please take a look at here:
https://github.com/nodejs/node/issues/7346#issuecomment-300432730
You can use Date() object to set specific time and then add a certain number of milliseconds to the date.
It definitly can because of how Javascript works (See Event Loop)
Javascript event loop executes the setInterval queue when other queued events are finished. These events will take some time and it will effect your setInterval function's execute time and it will eventually drift away as time passes.
setInterval should not drift in a perfect world. It might be delayed due to other things taking up system resources. If you need a more precise solution to what you have, use the clock() function to " calibrate " your nodes.
This question already has answers here:
Clock on webpage using server and system time?
(8 answers)
Closed 9 years ago.
I am working on a very time-sensitive web application. One of the business rules given to me is that the application's behavior must always depend on the time on the web server, regardless of what time is on the client's clock. To make this clear to the user, I was asked to display the server's time in the web application.
To this end, I wrote the following Javascript code:
clock = (function () {
var hours, minutes, seconds;
function setupClock(updateDisplayCallback) {
getTimeAsync(getTimeCallback);
function getTimeCallback(p_hours, p_minutes, p_seconds) {
hours = p_hours;
minutes = p_minutes;
seconds = p_seconds;
setInterval(incrementSecondsAndDisplay, 1000);
}
function incrementSecondsAndDisplay() {
seconds++;
if (seconds === 60) {
seconds = 0;
minutes++;
if (minutes === 60) {
minutes = 0;
hours++;
if (hours === 24) {
hours = 0;
}
}
}
updateDisplayCallback(hours, minutes, seconds);
}
}
// a function that makes an AJAX call and invokes callback, passing hours, minutes, and seconds.
function getTimeAsync(callback) {
$.ajax({
type: "POST",
url: "Default.aspx/GetLocalTime",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var date, serverHours, serverMinutes, serverSeconds;
date = GetDateFromResponse(response);
serverHours = date.getHours();
serverMinutes = date.getMinutes();
serverSeconds = date.getSeconds();
callback(serverHours, serverMinutes, serverSeconds);
}
})
}
return {
setup: setupClock
};
})();
The function passed in for updateDisplayCallback is a simple function to display the date on the web page.
The basic idea is that the Javascript makes an asynchronous call to look up the server's time, store it on the client, and then update it once per second.
At first, this appears to work, but as time goes by, the displayed time gets behind a few seconds every minute. I left it running overnight, and when I came in the next morning, it was off by more than an hour! This is entirely unacceptable because the web application may be kept open for days at a time.
How can I modify this code so that the web browser will continuously and accurately display the server's time?
Javascript's setInterval is not accurate enough to allow you to keep the time like this.
My solution would be:
Periodically get the server's time in milliseconds (it does not need to be very often as the two clocks will hardly deviate that much)
Get the client time in milliseconds
Calculate the clock deviation between server and client (client-server)
Periodically update the display of the clock by getting the client time and adding the clock deviation
Edit:
To be more accurate, you could measure the round trip time of the server's request, divide it by 2 and factor that delay into the clock deviation. Assuming round trips are symmetrical in their duration, this would give a more accurate calculation.
setInterval is not a reliable way to schedule time critical events. It may take less or more than 1000ms to run your callback depending on how busy JavaScript it is at the moment.
A better approach would be to take a shorter interval and use new Date().getTime() to check if a second has passed.
The minimum interval browsers allow is as high 10.
Thanks for the answers. I have up-voted both answers so far as they contain useful information. However, I am not using the exact answer prescribed in either answer.
What I finally decided on is a bit different.
I wrote about what I learned on my personal web page.
First of all, I now understand that using setInterval(..., 1000) is not good enough to have something done once per second for a long time. However, 'polling' the time with a much shorter interval looking for the second to change seems very inefficient to me.
I decided that it does make sense to keep track of the 'offset' between the server time and the client time.
My final solution is to do the following:
(1) Do an AJAX call to the server to get the time. The function also checks the client time and computes the difference between the server time and the client time, in milliseconds. Due to network latency and other factors, this initial fetch may be off by a few seconds. For my purposes, this is okay.
(2) Execute a tick function. Each time tick executes, it checks how long it has been since the last time tick executed. It will use this time to compute an argument to be passed to setTimeout so that the time display is updated approximately once per second.
(3) Each time the tick function computes the time to be displayed, it takes the client time and adds the difference that was computed in step (1). This way, I don't depend upon the client to have the time set correctly, but I do depend upon the client to accurately measure elapsed time. For my purposes, this is okay. The most important thing is that regardless of how setTimeout may be inaccurate or interrupted by other processes (such as a modal dialog, for instance), the time displayed should always be accurate.
Basically I would like to create a running ticker that continually (every 1-15 seconds, it doesn't matter) that would update that total amount energy savings that our company saved based on a set equation (such as 25 cents per minute). It would be based on the actual clock/calendar time, not just time that the visitor has accessed the page.
I'm looking to use javascript to do this (or jQuery) but I'm new to both languages with little experience.
Thanks!
Doing your calculations and updating them on a regular interval isn't very hard. You'll need to use the JavaScript Date Object to get your time. You can also use a setInterval function to perform your regular updates.
I don't know your level of knowledge about javascript but there are two function called window.setInterval and window.clearInterval that you can use to generate events at specific intervals.
you could use window.setInterval(function,time in milliseconds);
basically:
var money_value=0.25; //25 cents
var timing=15; //15 seconds
var global_calculator=0; //start time could be brought in by php or whatever
window.setInterval("calculate()",timing*1000); //timing*1000 milliseconds
// means 15 seconds
function calculate(){
global_calculator+=15; //add the passed seconds to the total of seconds
total=global_calculator*money_value; //calculate the total savings
update_clock(); //your function that updates the values some where to show them;
}
that should be it.