web端本地与服务端时间校验

当前校验逻辑: 本地和服务端的时间校验绑定在一个通用请求上,这个请求每七分钟会到服务端请求一次,本地拿到服务器时间后,计算请求服务器来回的时间,最后得出与服务器时间的差值,然后每次new Date().getTime() 时候都会加上这个差值,保证时间的准确性,时间精确度在毫秒。

问题描述:问题是出现在用户手动修改过本机时间后,第一个七分钟内时间都是错乱的,如果是七分钟后,再改回当前时间,又会有七分钟校验错误时间。

  在网络上着找到了很多关于这方面校验的资料,总结出几种方法,关于本地和服务端交互:

1. 本地打开计时器,在与服务端校验完成后的七分钟内,都由自己本机去进行时间轮询,每次获取时间不new date,而是直接从计时器中得到当前的时间。

大概实现逻辑:

function beginTimer () {
  // 100ms loop once
  currentTime += 100;

  if (timerId) {
    clearTimeout(timerId); // clear previous.
  }

  timerId = setTimeout(function () {
     beginTimer();
  }, 100); 
}

优点: 自己开的计时器,不受用户修改本机时间影响。

缺点: 缺点也很明显,setTimeOut 也只是加入到任务的最后,如果有其他任务在排队,它也只能等着,这样就会导致实际时间已经超过100ms,但是只加了100ms,此时获取到的时间就会有偏差,而且随着时间加长,偏差会越来越大,而且这样频繁的打开setTimeOut,说对网页性能完全没有影响,很显然不太现实。

2. 由于多端开发,参照手机端的校验方式是由后台唤醒之后,开始拿取离线消息,同时校验时间,我觉得也可以采用这样的一种方式,当程序被切到当前界面时,可以去与服务端校验一次时间,但PC端毕竟与手机相差很多,可以几秒内进行多次的,切进来,切出去,所以必然要有一种时间或者次数的限制,来避免自身频繁的进行服务器请求(未实现此方式,不贴代码了)

3. 这种方法跟第一种方式很像,但并不是自己开定时器来计算当前时间,而是针对自己修改了时间的用户,在开始new一个时间,然后每30秒,再次new一个时间,判断两个时间的差值,是否在我的预期范围内(误差10s),如果不在,则进行服务校验,这样就能保证用户在修改时间后的一分钟以内,我就能知道本机时间出现了问题,需要我来重新校验了。

大概实现逻辑:

var beginTime;
var timerId;
var defaultInterval = 30000; // check time difference.default: 30s.
var mixTimeDiff = 10000; // local time mix differece is 10s. 
var flush = true; // a lock. for prevent timer loops during init Timer.

function initTime () {
  flush = false;
  if (timerId) {
    clearTimeout(timerId);
  }
  beginTime = new Date().getTime();
  beginTimer();
}

function beginTimer () {

  let currentTime = new Date().getTime();

  if (flush && Math.abs(currentTime - beginTime) > defaultInterval + mixTimeDiff) {
    // check serverTime.
    console.error('current time is wrong! Recheck the server time.');
  }

  beginTime = currentTime; // reset begin time.

  if (timerId) {
    clearTimeout(timerId); // clear previous.
  }

  flush = true; // release lock.

  timerId = setTimeout(function () {
    if (flush) {
      beginTimer();
    }
  }, defaultInterval); 
}

module.exports = {
  initTime
}

优点:每30进行一次校验,频率并不是很高,对性能影响上也不会很大,同样在30s内就能了解到本地时间是否正常。

缺点:方法有点取巧,并未完全解决用户修改本地时间的问题,在这三十秒内,还是会出现发送时间有误的问题,但是修改时间的需求毕竟是少数,能在30m内纠正好,聊胜于无了。

原文地址:https://www.cnblogs.com/lhwblog/p/9406051.html