服务器和客户端之间同步时钟

4
在我的应用程序中,我有一个服务器和x个客户端。当客户端启动时,它从服务器获取当前系统时间。每个客户端都必须使用服务器时间工作,不能使用自己的系统时间。
现在我的问题是:如何最好地在客户端上运行一个时钟,以当前服务器时间开始,几乎同步运行,而无需每隔x秒接收一次服务器时间?
目标是在客户端上显示一个带有服务器时间的运行时钟。
客户端时钟可能具有的误差为24小时内的1秒左右。
在我的解决方案中,我设置了一个定时器,每500毫秒触发一次,并在定时器执行时对服务器时间计数500毫秒。但这不是一个好的解决方案,因为客户端时钟与服务器时间不同。
谢谢您的回复。

这是什么意图?你需要经常轮询时间吗?还是重新考虑你的解决方案,只在需要时获取时间可能更好? - Marthin
3
我会依靠现有的解决方案:http://en.wikipedia.org/wiki/Network_Time_Protocol(不过这并不能*强制*客户端使用服务器时间...) - Andreas Dolk
3个回答

3

在IT技术中,你应该使用已有的时钟同步方法,比如网络时间协议,而不是自己构建定制解决方案。这样做可以获得更好的结果,并且所有服务器都会同意当前时间是什么 :-)。


2
我找到了一个完美适合我情况的解决方案。不再使用System.currentTimeMillis(),而是使用System.nanoTime()System.nanoTime()与系统时钟无关。
当我接收到当前服务器时间时,我会额外保存来自系统的纳秒数。然后,当前服务器时间将使用从服务器时间接收的ns时间和当前nanoTime加上服务器时间之间的差异进行计算。
例如:
// The Client starts and receive the current Server time and the nanoTime
private long         serverTime = server.getCurrentTime();
private long         systemNano = System.nanoTime();

//To calculate the current Server time without a service call
                                                                        //ns-> ms
long currentServerTime = serverTime + ((System.nanoTime() - systemNano) / 1000000);

Thx


1

一种方法是获取服务器时间和本地时间之间的差异,并将其用于时间计算

  • 客户端启动并从服务器获取时间(我假设使用当前时间的毫秒数,但可以根据您使用的任何内容进行调整)
  • 客户端检查其当前系统时间并保存差异
  • 然后始终可以将差异应用于客户端上的当前系统时间以计算服务器时间

示例:

long serverTime = 1328860926471l; // 2012/02/10 10:02, received from wherever
long currentTime = System.currentTimeMillis(); // current client time
long difference = currentTime - serverTime;

// Server time can then me retrieved like this:
long currentServerTime = System.currentTimeMillis() - difference;     
Date serverTimeDate = new Date(currentServerTime);

显然,必须在接收到服务器时间的那一刻保存差异。


当客户端更改系统时间时会发生什么?这就是为什么我正在寻找一种不使用客户端的System.currentTimeMillis()解决方案的原因。 - Seffel
如果用户在程序运行时更改系统时间,那么这个解决方案将会给出错误的结果。因此,需要经常检查当前服务器时间。网络时间协议会给你最好的结果,前提是你能够使用它。 - Wilhelm Kleu
我认为这个不可行。它依赖于客户端时钟实际上是正确的,这也是问题所在。你只有一个时钟,就是服务器上的那个。 - mjs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接