来自服务器时间戳的JavaScript异步时钟

时间:2014-08-13 18:37:41

标签: javascript php asynchronous

目前,我正在使用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请求,而不是每秒发送一个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分钟与服务器同步一次。如何才能做到这一点?我在Google上做了一些研究,但我找不到一个简单的解释,只是自定义函数和对Node.js的引用,我没有使用它。任何帮助或建议将不胜感激。

2 个答案:

答案 0 :(得分:1)

我的方法是您可以使用本地时间来跟踪同步之间的毫秒数。然后,您可以将这些毫秒添加到上一个服务器时间。因此,有一个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
};

答案 1 :(得分:0)

在第一种方法中,您只需更改功能的第二个参数&#39; setInterval&#39;从 1000 5 * 60 * 1000 因为这是以毫秒为单位的延迟。现在它将每5分钟获取一次。

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

根据@ jwatts1980的评论更新:

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);
}