具有良好的precision(大于0.5秒)在javascript同步时间(NTP状) [英] Synchronize time in javascript with a good precision (>0.5s) (NTP-like)

查看:245
本文介绍了具有良好的precision(大于0.5秒)在javascript同步时间(NTP状)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在寻找一种方式来带好precision同步客户端之间的时间(比方说0.5秒,至少)。

我排除使用jsontime或利用时间戳服务器响应头由于家境precision(第二个或者更少)。

更新: 它应该与移动连接的工作甚至。这不是不频繁(比如这里意大利)的3G连接本身具有0.5s左右的往返时间,所以算法是稳健的。

解决方案

度假的好老 ICMP时间戳信息规划。 。这是相当琐碎的JavaScript和PHP来实现。

下面是该方案的使用JavaScript和PHP的实现:

  // browser.js

VAR请求=新XMLHtt prequest();
request.onreadystatechange = readystatechangehandler;
request.open(POST,http://www.example.com/sync.php,真正的);
request.setRequestHeader(内容类型,应用程序/ x-WWW的形式urlen codeD);
request.send(原=+(新日期).getTime());

功能readystatechangehandler(){
    VAR返回=(新日期).getTime();
    如果(request.readyState === 4和&安培; request.status === 200){
        VAR时间戳= request.responseText.split('|');
        VAR原= +时间戳[0];
        VAR收到= +时间戳[1];
        变种发射= +时间戳[2];
        VAR发送=接受 - 原件;
        VAR接收=返回 - 发送;
        VAR往返=发送+接收;
        VAR单向=往返/ 2;
        VAR差=发送 - 单向; //这是你想要的
        //所以服务器时间将客户端时间+差
    }
}
 

现在的 sync.php code:

 < PHP
    $得到= ROUND(microtime中(真)* 1000);
    回声$ _ POST [原创。 '|';
    回声$接受。 '|';
    回声轮(microtime中(真)* 1000);
?>
 

我没有测试上面的code,但它应该工作。

注意:下面的方法将准确地计算出客户端,并提供实际的时间来发送和接收邮件服务器之间的时间差是相同或大致相同。考虑以下情形:

 时客户机服务器
-------- -------- --------
原创0 2
接收3 5
发送4 6
返回7 9
 

  1. 正如你所看到的,在客户端和服务器的时钟是2个单位关闭同步。因此,当客户端发送时间戳请求,它记录了原始时间为0。
  2. 服务器收到请求3个单位后,但记录的接收时间为5个单位,因为它是2台前方。
  3. 然后一个单位后发送时间戳答复,并记录发送时间为6个单位。
  4. 的客户机(根据服务器即在9个单位)接收应答后3个单位。但是,由于它的2台服务器之后,它记录了返回的时间为7台。

使用这些数据,我们可以计算出:

 发送=接收 - 原始= 5  -  0 = 5
接收=返回 - 发送= 7  -  6 = 1
往返=发送+接收= 5 + 1 = 6
 

正如你从上面可以看到,发送和接收时间计算错误,这取决于客户端和服务器有多少是关闭同步。然而,往返时间将永远是正确的,因为我们首先将两个单位(接收+原装),再减去两个单位。(回来了 - 发送)

如果我们假设单向时间总是一半的往返时间(即传输时间是接收的时候,那么我们就可以很容易地计算出时间差,如下所示):

 单向=往返/ 2 = 6/2 = 3
差=发送 - 单向= 5  -  3 = 2
 

正如你所看到的,我们准确地计算出的时间差为2个单位。该公式的时间差始终发送 - 单向的时间。然而,这个方程的准确性取决于你如何精确计算出单向的时间。如果发送和接收的邮件的实际时间不等于或约等于,你需要找到计算的一种方法时一些其他的方式。然而,你的目的,这应该足够了。

I'm looking for a way to synchronize time between clients with a good precision (let's say 0.5 seconds at least).

I exclude using jsontime or exploiting timestamp in server response headers due to a poor precision (a second or maybe less).

UPDATE: It should work even with mobile connections. It's not unfrequent (e.g. here in Italy) that 3G connections itself have a round trip time around 0.5s, so algorithm has to be robust.

解决方案

Resort to the good old ICMP Timestamp message scheme. It's fairly trivial to implement in JavaScript and PHP.

Here's an implementation of this scheme using JavaScript and 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
    }
}

Now for the sync.php code:

<?php
    $receive = round(microtime(true) * 1000);
    echo $_POST["original"] . '|';
    echo $receive . '|';
    echo round(microtime(true) * 1000);
?>

I haven't tested the above code, but it should work.

Note: The following method will accurately calculate the time difference between the client and the server provided that actual time to send and receive messages is the same or approximately the same. Consider the following scenario:

  Time    Client   Server
-------- -------- --------
Original        0        2
Receive         3        5
Transmit        4        6
Returned        7        9

  1. As you can see, the client and server clocks are 2 units off sync. Hence when the client sends the timestamp request, it records the original time as 0.
  2. The server receives the request 3 units later, but records the receive time as 5 units because it's 2 units ahead.
  3. Then it transmits the timestamp reply one unit later and records the transmit time as 6 units.
  4. The client receives the reply after 3 units (i.e. at 9 units according to the server). However, since it's 2 units behind the server it records the returned time as 7 units.

Using this data, we can calculate:

Sending = Receive - Original = 5 - 0 = 5
Receiving = Returned - Transmit = 7 - 6 = 1
Roundtrip = Sending + Receiving = 5 + 1 = 6

As you can see from above, the sending and receiving times are calculated incorrectly depending upon how much the client and server are off sync. However, the roundtrip time will always be correct because we are first adding two units (receive + original), and then subtracting two units (returned - transmit).

If we assume that the oneway time is always half of the roundtrip time (i.e. the time to transmit is the time to receive, then we can easily calculate the time difference as follows):

Oneway = Roundtrip / 2 = 6 / 2 = 3
Difference = Sending - Oneway = 5 - 3 = 2

As you can see, we accurately calculated the time difference as 2 units. The equation for time difference is always sending - oneway time. However, the accuracy of this equation depends upon how accurately you calculate the oneway time. If the actual time to send and receive the messages is not equal or approximately equal, you'll need to find some other way to calculate the one way time. However, for your purposes this should suffice.

这篇关于具有良好的precision(大于0.5秒)在javascript同步时间(NTP状)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆