zoukankan      html  css  js  c++  java
  • 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内纠正好,聊胜于无了。

  • 相关阅读:
    Java基础06 组合
    纸上谈兵: 树, 二叉树, 二叉搜索树
    Java基础05 实施接口
    纸上谈兵: 队列 (queue)
    纸上谈兵: 数学归纳法, 递归, 栈
    Java基础01 从HelloWorld到面向对象
    纸上谈兵: 表 (list)
    Java基础02 方法与数据成员
    纸上谈兵: 排序算法简介及其C实现
    纸上谈兵: 栈 (stack)
  • 原文地址:https://www.cnblogs.com/lhwblog/p/9406051.html
Copyright © 2011-2022 走看看