同步(!)60000 ms在每个设备上循环。没有不准确

时间:2015-11-04 20:21:01

标签: javascript loops time synchronization

这对你们中最专业的人来说很明显。

我正在计划一个(Javascript) - 一分钟动画的永不结束循环。

bbac
到目前为止,这么好。

我希望,循环在每个设备,每个操作系统,任何浏览器上都是同步的,从世界各地的任何地方完全以毫秒为单位。没有不妥之处。

我的尝试是:通过Ajax获取服务器时间的秒数(知道补间 - 否)和毫秒(知道,当下一个补间开始时)。然后,让动画在x毫秒之后从Tween(x)开始。但它没有同步。最多有2秒的差异。

我该如何解决?请不要说,这是不可能的,它必须在任何地方都可以!

如果javascript无法实现,请告诉我其他内容。

非常感谢。

1 个答案:

答案 0 :(得分:0)

最残酷的是实施NTP,但如果半秒差异就足够了,你可以实施简化版。

主要方法是在时间服务器和客户端之间开始通信,以获得a)时间和b)客户端时间和服务器时间之间的差异。使用一个只有秒表的小型服务器程序,您可以执行以下操作:

服务器 - >客户端:服务器时间(或从客户端 - >服务器开始)

客户端:将自己的时间设置为服务器时间

客户 - >服务器:客户端时间

(你可以重复几次以获得平均值)

服务器现在可以计算延迟时间并将其发送给客户端,客户端会相应地更正其时间。您可以在Javascript中设置客户端的计算机时间,您只能设置实际会话的时间,因此您需要重复每次重新加载以及介于两者之间的时间(不是经常,我会说每小时一次就足够了。)

开销应该尽可能小,如果可能的话,使用比HTTP更小的协议是个好主意

在服务器端使用PHP的一个小而匆忙的例子:

<?php
  $client_ts = $_GET["date"];
  // UTC timestamp in milliseconds
  $server_ts = round(microtime(true) * 1000);
  // send back that timestamp and the lag
  echo $server_ts."|".($client_ts - $server_ts);
?>

HTML

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>LAG test</title>
<style type="text/css">
table {
  margin-left: 1em;
}
td,th {
  border: 2px solid black;
  padding: .5ex .5em .5ex .5em;
  text-align: center;
}
input {
  margin: 3ex 1em 0 4em;
}
p {
  max-width: 40em;
}
</style>
<script type="text/javascript">
// everything is highly simplified and crude here! No checks, no balances!

// Simple AJAX. Websockets would be better, of course, but also way more complex
var ajax_request;
function get_data(){
  var ret, lag, diff,client_time, server_time;
  if (ajax_request.readyState === 4){
    if (ajax_request.status === 200){
      ret = ajax_request.responseText;
    }
    else{
      ret = null;
    }
  }
  else {
    ret = null;
  }
  if(ret){
    // only one check here, more are better especially
    // if 'diff' is very large
    client_time = Date.now();
    server_time = ret.split("|");
    lag = server_time[1];
    diff = Math.abs(client_time - server_time[0]);

    document.getElementById("ctos").textContent = lag;
    document.getElementById("stoc").textContent = diff;
    document.getElementById("diff").textContent = (lag - diff);
  }
  else {
    document.getElementById("ctos").textContent = "Nope";
    document.getElementById("stoc").textContent = "Nada";
    document.getElementById("diff").textContent = "Rien";
  }
}

function sendTo(text,uid,url){
  ajax_request  = new XMLHttpRequest();
  ajax_request.open("GET", url + "?date=" + text + "u=" + uid, true);
  ajax_request.send(null);
  ajax_request.onreadystatechange = get_data;
}

function testLAG(){
  // cheap pseudo-UID to avoid caching
  var unifier = Math.floor(Math.random() * 0xffffffff).toString();
  // date.now() returns UTC time
  var client_time = Date.now();
  sendTo(client_time,unifier ,"phpdate.php");
}

</script>
</head>
<body>
<h1> To test lag, press LAG-Button</h1>
<p>The difference in "Diff." is the probablity that it was the same route both ways. You need to allow for some milliseconds for the HTTP overhead but in general: the lower the better.</p>
<table id="out" caption="latencies">
<tr><th>Client to Server</th><th>Server to Client</th><th>Diff.</th></tr>
<tr><td id="ctos">n/a</td><td id="stoc">n/a</td><td id="diff">n/a</td>
</table>
<input type="button" value="LAG-Button" onclick="testLAG()" /> &lt;- press here and press often. But only if you don't mind.
</body>
</html>