Synchronize time in javascript with a good precision (>0.5s) (NTP-like)

前端 未结 2 1404
谎友^
谎友^ 2020-12-13 15:58

I\'m looking for a way to synchronize time between clients with a good precision (let\'s say 0.5 seconds at least).

I exclude using jsontime or exploiting timestamp

2条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-13 16:36

    If you just want to sync the timeclock on several computers, NTP themselves recommend setting up your own timeserver.

    Server Endpoint

    Set up an api endpoint on your server i.e.

    http://localhost:3000/api/time
    

    returns:

    status: 200, 
    body: { time: {{currentTime}} }
    

    How this is done will depend on the backend language that you're using.

    Client Code

    Given such an endpoint, this JS snippet I threw together will

    1. Poll your server endpoint 10 times.
    2. Attempt to compensate for latency by removing half of the round-trip time.
    3. Report the average offset between the server and the client.

    var offsets = [];
    var counter = 0;
    var maxTimes = 10;
    var beforeTime = null;
    
    // get average 
    var mean = function(array) {
      var sum = 0;
      
      array.forEach(function (value) {
        sum += value;
      });
      
      return sum/array.length;
    }
    
    var getTimeDiff = function() {
      beforeTime = Date.now();
      $.ajax('/api/time', {
          type: 'GET',
          success: function(response) {
              var now, timeDiff, serverTime, offset;
              counter++;
              
              // Get offset
              now = Date.now();
              timeDiff = (now-beforeTime)/2;
              serverTime = response.data.time-timeDiff;
              offset = now-serverTime;
              
              console.log(offset);
              
              // Push to array
              offsets.push(offset)
              if (counter < maxTimes) {
                // Repeat
                getTimeDiff();
              } else {
                var averageOffset = mean(offsets);
                console.log("average offset:" + averageOffset);
              }
          }
      });
    }
    
    // populate 'offsets' array and return average offsets
    getTimeDiff();

    You can use this computed offset (just add it to local time), to determine a common "universal" time from each client's context.

提交回复
热议问题