ajax+withrquest,ajax - The best way to synchronize client-side javascript clock with server date - S...

I've found that the algorithm of @mehdi-yeganeh above didn't give me useful results but the idea is sound: to use the NTP algorithm (or at least a weak version of it) to synchronize the server and client clocks.

This is my final implementation, it uses the server response headers if available for extra accuracy (please correct me if I'm wrong, my own tests say this is quite accurate).

browser-side (javascript):

// the NTP algorithm

// t0 is the client's timestamp of the request packet transmission,

// t1 is the server's timestamp of the request packet reception,

// t2 is the server's timestamp of the response packet transmission and

// t3 is the client's timestamp of the response packet reception.

function ntp(t0, t1, t2, t3) {

return {

roundtripdelay: (t3 - t0) - (t2 - t1),

offset: ((t1 - t0) + (t2 - t3)) / 2

};

}

// calculate the difference in seconds between the client and server clocks, use

// the NTP algorithm, see: http://en.wikipedia.org/wiki/Network_Time_Protocol#Clock_synchronization_algorithm

var t0 = (new Date()).valueOf();

$.ajax({

url: '/ntp',

success: function(servertime, text, resp) {

// NOTE: t2 isn't entirely accurate because we're assuming that the server spends 0ms on processing.

// (t1 isn't accurate either, as there's bound to have been some processing before that, but we can't avoid that)

var t1 = servertime,

t2 = servertime,

t3 = (new Date()).valueOf();

// we can get a more accurate version of t2 if the server's response

// contains a Date header, which it generally will.

// EDIT: as @Ariel rightly notes, the HTTP Date header only has

// second resolution, thus using it will actually make the calculated

// result worse. For higher accuracy, one would thus have to

// return an extra header with a higher-resolution time. This

// could be done with nginx for example:

// http://nginx.org/en/docs/http/ngx_http_core_module.html

// var date = resp.getResponseHeader("Date");

// if (date) {

// t2 = (new Date(date)).valueOf();

// }

var c = ntp(t0, t1, t2, t3);

// log the calculated value rtt and time driff so we can manually verify if they make sense

console.log("NTP delay:", c.roundtripdelay, "NTP offset:", c.offset, "corrected: ", (new Date(t3 + c.offset)));

}

});

server-side (php, but could be anything):

Your server at route 'GET /ntp' should return something like:

echo (string) round(microtime(true) * 1000);

If you have PHP >5.4, then you can save a call to microtime() and make it a bit more accurate with:

echo (string) round($_SERVER['REQUEST_TIME_FLOAT'] * 1000);

NOTE

This way might be seen as kind of ghetto, there are some other Stack Overflow answers that could guide you towards a better solution:

Notably, this solution has been offered a few times: https://github.com/NodeGuy/ServerDate. It seems like this is a tad bit more work to setup but should provide better accuracy.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值