mic*_*red 13 javascript ajax time ntp
我正在寻找一种方法来同步客户端之间的时间与精度(让我们说至少0.5秒).
由于精度差(一秒或更短),我排除了使用jsontime或利用服务器响应头中的时间戳.
更新:它应该适用于移动连接.3G连接本身的往返时间大约为0.5秒并不罕见(例如在意大利),因此算法必须是健壮的.
Aad*_*hah 17
求助于良好的旧ICMP时间戳消息方案.在JavaScript和PHP中实现它是相当简单的.
这是使用JavaScript和PHP的这个方案的实现:
// browser.js
var request = new XMLHttpRequest();
request.onreadystatechange = readystatechangehandler;
request.open("POST", "http://www.example.com/sync.php", true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send("original=" + (new Date).getTime());
function readystatechangehandler() {
var returned = (new Date).getTime();
if (request.readyState === 4 && request.status === 200) {
var timestamp = request.responseText.split('|');
var original = + timestamp[0];
var receive = + timestamp[1];
var transmit = + timestamp[2];
var sending = receive - original;
var receiving = returned - transmit;
var roundtrip = sending + receiving;
var oneway = roundtrip / 2;
var difference = sending - oneway; // this is what you want
// so the server time will be client time + difference
}
}
Run Code Online (Sandbox Code Playgroud)
现在sync.php代码:
<?php
$receive = round(microtime(true) * 1000);
echo $_POST["original"] . '|';
echo $receive . '|';
echo round(microtime(true) * 1000);
?>
Run Code Online (Sandbox Code Playgroud)
我没有测试上面的代码,但它应该工作.
注意:如果发送和接收消息的实际时间相同或大致相同,则以下方法将准确计算客户端与服务器之间的时间差.请考虑以下情形:
Time Client Server
-------- -------- --------
Original 0 2
Receive 3 5
Transmit 4 6
Returned 7 9
Run Code Online (Sandbox Code Playgroud)
使用这些数据,我们可以计算:
Sending = Receive - Original = 5 - 0 = 5
Receiving = Returned - Transmit = 7 - 6 = 1
Roundtrip = Sending + Receiving = 5 + 1 = 6
Run Code Online (Sandbox Code Playgroud)
从上面可以看出,发送和接收时间的计算方式不正确,具体取决于客户端和服务器的同步程度.但是,往返时间总是正确的,因为我们首先添加两个单位(接收+原始),然后减去两个单位(返回 - 发送).
如果我们假设单向时间总是往返时间的一半(即发送时间是接收时间,那么我们可以很容易地计算时间差,如下所示):
Oneway = Roundtrip / 2 = 6 / 2 = 3
Difference = Sending - Oneway = 5 - 3 = 2
Run Code Online (Sandbox Code Playgroud)
如您所见,我们准确地将时差计算为2个单位.时差的等式总是sending - oneway时间.但是,此等式的准确性取决于您计算单程时间的准确程度.如果发送和接收消息的实际时间不相等或大致相等,则需要找到其他方法来计算单向时间.但是,为了您的目的,这应该足够了.
如果您只是想在多台计算机上同步时钟,NTP 本身建议设置您自己的时间服务器。
在您的服务器上设置一个 api 端点,即
http://localhost:3000/api/time
Run Code Online (Sandbox Code Playgroud)
返回:
status: 200,
body: { time: {{currentTime}} }
Run Code Online (Sandbox Code Playgroud)
如何做到这一点取决于您使用的后端语言。
鉴于这样的端点,我拼凑的这个 JS 片段将
http://localhost:3000/api/time
Run Code Online (Sandbox Code Playgroud)
您可以使用此计算出的偏移量(只需将其添加到本地时间),从每个客户端的上下文中确定一个通用的“通用”时间。
| 归档时间: |
|
| 查看次数: |
9448 次 |
| 最近记录: |