Search code examples
javascriptphptimetimer

How to have server side countdown timer in javascript?


I am currently building this timer on a webview where the timer will automatically updates with javascript and the timer will decrement every second.

The current problem is that when a user makes the phone go to sleep, the timer doesn't update accordingly and the countdown will be a bit off so I would want to update the timer through server side instead of relying on a function that will break if a user makes the phone go to sleep. Here is the current code that I have

<h2 id="timer"> 
   1:00
<h2>

<script>
   var countdown = new Date("<?php echo $row['end_timer'] ?>").getTime();
   var now = new Date("<?php echo date('Y-m-d H:i:s') ?>")

     var x = setInterval(function() {

         // Increase the distance by 1
         now.setSeconds(now.getSeconds() +                                           

         var distance = countdown - (now.getTime());

         var seconds = Math.floor((distance % (1000 * 60)) / 1000);

          document.getElementById("timer").innerHTML = (seconds < 10 ? '0' : '') + seconds;

          if (distance < 0) {
             clearInterval(x);
             document.getElementById("timer").innerHTML = "00";
             location.reload();
           }
     }, 1000);
</script>

Solution

  • I can think of three ways to sync the countdown with the server.

    1. Send an AJAX request every second or when the phone wakes
    2. Use Server Sent Events
    3. Use WebSockets

    But there is a much simpler way. You can just rewrite your JS. You are adding 1 second to your now variable. But that does not work because setInterval does not call its callback in the specified interval (1000 ms in your case) if the phone is sleeping. So you add one second to now although more than one second has passed.

    var countdown = new Date(Date.now()+30*1000) // Countdown will end in 30 sec from now
    var cdElem = document.getElementById("coutdown");
    
    function displayCountdown() {
      //Time until the end of the countdown in ms
      var deltaTime = countdown.getTime() - Date.now();
      if(deltaTime < 0) {
        clearInterval(intervalId)
        deltaTime = 0;
      }
      cdElem.innerText = Math.round(deltaTime/1000);
    }
    
    var intervalId = setInterval(displayCountdown, 1000);
    displayCountdown()
    <h1 id="coutdown"></h1>