0

I'm building a live chess app, and I'm trying to add a timer to it. However, I am struggling to find a way to make the timer accurate. I have run some tests, and setInterval and setTimeout are extremely inaccurate, with a ten minute timeout being off by over three minutes. I also tried using setInterval with in interval of 100ms, but even that was off by over minute, when the tab was not active. That was just with the javascript window.setInterval; with nodejs, it hasn't been more than 10ms off, but I'm afraid it will if the server gets busy. I'm hoping to find a way to have the game end within at least a tenth of a second of the real time.

Any suggestions? Thanks!

jjroley
  • 157
  • 10
  • 3
    If your timeout is so large, why not just check the current time and subtract from the start time using Date API? OS timers are notoriously not accurate. – JBaczuk Mar 03 '22 at 21:10
  • I agree with using the date API. I would use Date.now() for the unix timestamp and compare it to the previous Date.now() – Cal Irvine Mar 03 '22 at 21:17
  • Adding on to everyone's comments, it's important that you never trust the timestamp sent from the client, although you can run it on the client just to display the UI. – code Mar 03 '22 at 22:18
  • I am using the Date API, but how can I use that to trigger a response at a set time? If the callback in the timeout gets called even a second behind, knowing the time since the start time won't be helpful. (if you know what I mean) Should I maybe have an interval of 100ms that updates the time? Or would it still be prone to large inaccuracies? – jjroley Mar 03 '22 at 22:26
  • Please provide enough code so others can better understand or reproduce the problem. – Community Mar 04 '22 at 05:42

1 Answers1

1

an ideal approach would be to use absolute clock time to get time elapsed and timer to have that check.

Something like code below.

const startTime = new Date();

const maxTime = 5 * 1000; // 60 seconds
setInterval(() => {
  checkExpired();
}, 300);

function checkExpired() {
  const curTime = new Date();

  timeDifference = Math.abs(curTime.getTime() - startTime.getTime());

  if (timeDifference > maxTime) {
    console.log("time up");
  }
}

The browser will not run setInterval as required due to performance reason. https://usefulangle.com/post/280/settimeout-setinterval-on-inactive-tab

If you need to run timer with required interval then it can be run in worker thread.

some info here. How can I make setInterval also work when a tab is inactive in Chrome?

But my guess is increased granularity is fine for non active tab.

indolentdeveloper
  • 1,253
  • 1
  • 11
  • 15