JavaScript异步时钟从服务器时间戳

JavaScript Asynchronous Clock from Server Time Stamp

本文关键字:服务器 时间戳 时钟 异步 JavaScript      更新时间:2023-09-26

目前,我正在使用XMLHTTPRequest从Apache服务器获取时间和日期。下面的代码显示了…

$(document).ready(function() {
    $("#loadtime").load("getdatetime.php");
    setInterval(function() {
        $("#loadtime").load('getdatetime.php?randval=' + Math.random());
    }, 1000);
    $.ajaxSetup({cache: false});
});

显然我不想每秒钟都发送一个http请求。下面是我正在试验的一些代码。

function getTime() {
    var hr = new XMLHttpRequest();
    var url = "getdatetime.php";
    var myRandom = parseInt(Math.random() * 999999999);
    hr.open("GET", url + "?rand=" + myRandom, true);
    hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    hr.onreadystatechange = function() {
        if (hr.readyState === 4 && hr.status === 200) {
            var serverTimeStamp = hr.responseText;
            var displayTime = Date(serverTimeStamp);
            document.getElementById("clock").innerHTML = displayTime;
        }
    };
    hr.send(null);
    return false;
}

上面的函数通过PHP内置的time()函数获取一个PHP时间戳,该函数返回自UNIX纪元以来的秒数。PHP时间戳可以方便地放在JavaScript的Date()函数中。所以现在我可以通过HTTP请求返回服务器的时间。目标是每5分钟发送一个HTTP请求,而不是每秒钟。因此,每隔5分钟,我需要获取Apache时间戳,然后迭代该时间戳…

// Sudo code:
// serverTimeStamp += 1000 (milliseconds)
// iterate on serverTimeStamp for 5mins
// send new HTTP request to get current Apache time stamp
// restart iteration, etc...

我已经发现,我不知道如何在serverTimeStamp上异步迭代。我需要时钟实时迭代,然后每5分钟与服务器同步。如何做到这一点?我在谷歌上做了一些研究,但我找不到一个简单的解释,只是自定义函数和对Node.js的引用,我不使用。如有任何帮助或建议,不胜感激。

我的方法是,您可以使用本地时间跟踪同步之间的毫秒数。然后,可以将这些毫秒数添加到上次服务器时间中。因此,有一个1秒计时器,它将上次同步以来的时间添加到每5分钟从服务器检索的时间中。

在这里使用毫秒似乎是最好的选择,因为它是服务器时间和JavaScript时间之间的常数度量。另外,.setTime(mills).getTime()很容易设置/获取。

我用jQuery写这个,因为您在AJAX示例中使用它。我将在纯JS中重写它,但这里是jQuery版本:

<script>
    $(document).ready(function() {
        var jsTime = (new Date()).getTime();
        var serverTime = (new Date()).getTime();
        var getServerTime = function() {
            $.get('getdatetime.php?randval=' + Math.random(), function(data) {
                serverTime = (new Date(data)).getTime(); //set the milliseconds from the server
                jsTime = (new Date()).getTime(); //set the JS mills for reference
            });
        };
        var setTime = function() {
            var currentTime = (new Date()).getTime(); //get the JS mills now
            var mills = serverTime + (currentTime - jsTime); //add the number of mills since the last sync
            var newServerTime = (new Date()).setTime(mills); //create the new adjusted sync time
            $("#loadtime").html(newServerTime); //set the value
        };
        getServerTime(); //sync now
        setInterval(getServerTime, 5*60*1000); //sync every 5 minutes
        setTime(); //set now
        setInterval(setTime, 1000); //set every second
        $.ajaxSetup({cache: false});
    });
</script>

这里是纯JS

window.onload = function() {
    var serverTime = (new Date()).getTime();
    var jsTime = (new Date()).getTime();
    var getServerTime = function() {
        var hr = new XMLHttpRequest();
        var url = "getdatetime.php";
        var myRandom = parseInt(Math.random() * 999999999);
        hr.open("GET", url + "?rand=" + myRandom, true);
        hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        hr.onreadystatechange = function() {
            if (hr.readyState === 4 && hr.status === 200) {
                serverTime = (new Date(hr.responseText)).getTime(); //set the milliseconds from the server
                jsTime = (new Date()).getTime(); //set the JS mills for reference
            }
        };
        hr.send(null);
    };
    var setTime = function() {
        var currentTime = (new Date()).getTime(); //get the JS mills now
        var mills = serverTime + (currentTime - jsTime); //add the number of mills since the last sync
        var newServerTime = (new Date()).setTime(mills); //create the new adjusted sync time
        document.getElementById("clock").innerHtml = newServerTime; //set the value
    };
    getServerTime(); //sync now
    setInterval(getServerTime, 5*60*1000); //sync every 5 minutes
    setTime(); //set now
    setInterval(setTime, 1000); //set every second
};

在第一种方法中,您可以将函数'setInterval'的第二个参数从1000更改为5*60*1000,因为这是以毫秒为单位的延迟。现在它每5分钟取一次时间。

setInterval(function() {
    $("#loadtime").load('getdatetime.php?randval=' + Math.random());
}, 5*60*1000);

根据@jwatts1980 的评论UPDATE:

var serverTimeStamp=0;
var url = "getdatetime.php";
var clock;
$(document).ready(function() {
   getTime();
}
function startIteration(){
   var after5min=serverTimeStamp+300000;  //300000 = 5*60*1000
   clock=setInterval(function() {
     serverTimeStamp+=1000;
     //-------------
     if(serverTimeStamp >= iteration){
        clearInterval(clock); //to end the iteration
        getTime(); //initiate new request
     }
   }, 1000);
}
function getTime(){
   var myRandom = parseInt(Math.random() * 999999999);
   var hr = new XMLHttpRequest();
   hr.open("GET", url + "?rand=" + myRandom, true);
   hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   hr.onreadystatechange = function() {
      if (hr.readyState === 4 && hr.status === 200) {
          serverTimeStamp = hr.responseText;
          var displayTime = Date(serverTimeStamp);
          document.getElementById("clock").innerHTML = displayTime;
          startIteration(); // restart iteration for 5 min OR etc...
      }
   };
   hr.send(null);
}