How to have a timer which cannot be modified in javascript? - 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);
}());

Related

Countdown timer with remote server - React native

I have an app that requires countdown timer. Due date comes from my back-end with rest api. I need to coundown remaining time in my react native app. But I can't use smart phone's time. Because user can be in different timezone / country etc. How i can use server's due date response for react native?
Should I send also remaining time in seconds to user? So I can countdown that remaining time every second?
https://www.example.com/getDueDate [POST]
returns:
Y-m-d H:i:s (future) time like 2021-05-20 23:40:40
If I use classic countdown approach for javascript, I need to use smart phone's time. But I don't want to use that.
NTP server approach can be tricky for react-native side. It just simple counter.
Why not send both the server's current time and the due date? Then start your timer from there?
That being said, the time will still be off by the roundtrip time between your user and the server (which will depend on their internet connection and your server's response time).
Yes, it is possible to get time. I'm also using rest api (token base authentication and expiry token after certain time). I'm checking as given below
var l_currentDateTimeSeconds;
l_currentDateTimeSeconds=((new Date().getTime() - "your_time_from_api") / 1000);
if (parseInt(l_CurrentDateTimeSeconds) < parseInt(your_time_from_api))
{
//failure case ;
}
else
{
//Success case;
}
output of time (in variable) will be in seconds. Visit given below link, it may be help
https://aboutreact.com/react-native-get-current-date-time/
This is the technique i use and it's really effective.
Step 1.
Send due date from server (5pm)
Send current time from server (4pm)
Step 2.
Check clients current time (3pm)
Subtract currentTime(server) - currentTime(client) and call it timeOffset
Step 3.
setInterval to run every second using the code example below.
//import useState, useEffect from react-native
const [timer,setTimer]=useState();
var serverExpiryDate="'the time the event will expire gotten from server";
var currentTimeAtServer="the time you got from server via api";
var currentTimeAtDevice=new Date().getTime();
const timeOffset= currentTimeAtServer - currentTimeAtDevice;
//timeOffset is the time difference between the user's clock and the server clock. Calculated when user received response from server.
useEffect(() => {
let interval = setInterval(() => {
setTimer(() => {
let endT = new Date(serverExpiryDate).getTime(); //time from server;
let nowT = new Date().getTime(); //current time on user've device
nowT = nowT + timeOffset; //VERY IMPORTANT, helps to sync user's time with server.
let remaining = endT >= nowT ? Math.floor((endT - nowT) / 1000) : 0;
let stopCheck = remaining === 0 ? clearInterval(interval) : null;
return remaining;
});
}, 1000); //each count lasts for a second
return () => {
clearInterval(interval);
};
}, []);
console.log(timer) //this will be decreasing every second

Alarms in NodeJS (without any delay)

I am currently attempting to make an alarm system for a website that I control my sprinklers with.
Currently, I use sockets to get alarms from the client and store them in a JSON file in the server.
To "activate" the alarms, I have thought to have a setInterval function that checks whether the current time is included in the array (using .includes() )
I am very annooyed currently because the setInterval function is delays 65 milliseconds every time it is run
Does it wait for the code inside to finish before continuing? If so, how do I make it not do so
This is my code:
I think this may be relevant, if I could understand it (I am new)
console.log("Waiting for time to get in to sync...")
while (sync > 0 || sync == undefined) {
let date = new Date()
sync = date.getSeconds()
}
setInterval(()=>{
check(new Date()) //run the check code elsewhere
}, 60000); // one minute delay```

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

How to call a javascript function after a fixed time delay from a fixed time considering page refresh

I have a use case in which a function needs to be called after 30 minutes from a fixed time. Say the fixed time is 16:30:48 and the function needs to be called after 30 minutes from 16:30:48. User might refresh the page but this should not affect the timing of calling the javascript function. The function should be called at 17:00:48 no matter how many page refreshes the user makes.
Is there a method in javascript that takes the time or Date in a function and execute the function at that time.
Is there a way in javascript to achieve that?
Thanks.
Some notes:
Because of the page refresh, the only real way to do this is to store the first page load time in a cookie or local storage if your target browsers support it.
You'll need to not replace that cookie or local storage item if you see it's already there.
If using a cookie, you'll need to store the date as a string, so probably best to get the "milliseconds since The Epoch" value (yourDate.getTime()) and then store the string version of that.
Compare the resulting epoch-ms value to the current date's epoch-ms value and, if it's been 30 minutes, issue your alert or what-have-you. If it hasn't (yet) been, set up a timer on the current page to fire when it has been.
So in pseudo-code:
var existingValue, remaining, THIRTY_MINUTES;
THIRTY_MINUTES = 30 * 60 * 1000;
existingValue = getExistingValueFromCookieOrLocalStorage("myvalue");
if (!existingValue || existingValue > SOME_STALE_AMOUNT) {
// First page load / existing value is stale, start again
putValueInStorage("myvalue", String(new Date().getTime()));
}
else {
// We have the value, how long left?
remaining = THIRTY_MINUTES - (new Date().getTime() - Number(existingValue));
if (remaining <= 0) {
// It's time!
trigger();
}
else {
// Not yet, schedule the timer -- this will get wiped out by
// a page reload
setTimeout(trigger, remaining);
}
}
function trigger() {
showTheAlert();
removeValueFromStorage("myvalue");
}
You could save a cookie with the time to execute the function and examine the cookie when the page is loaded. Otherwise for in-page timing, a setTimeout() should suffice.
Assuming cookies are enabled, you could set a cookie when the user first enters the site (checking one isn't already in existence) with the time +30 mins. Then do a window.setTimeOut () calling your function. This way, is the user refreshes the window you can pull back the cookie fetching your target time, then recalculate how long until your function should be called, then setup a new window.setTimeOut()

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.

Categories

Resources