9

我目前正在尝试构建一个应用程序,该应用程序本质上需要跨服务器和每个客户端进行良好的时间同步。我的应用程序有一些替代设计可以消除这种同步需求,但是当它不存在时,我的应用程序很快就会开始变得糟糕。

万一我遗漏了什么,我的基本问题是:同时在多个位置触发一个事件。据我所知,这样做的唯一方法需要某种时间同步,但我可能错了。我尝试以不同的方式对问题进行建模,但这一切都归结为a)一个糟糕的应用程序,或者b)需要时间同步。

假设我真的真的需要同步时间。

我的应用程序是基于 Google AppEngine 构建的。虽然 AppEngine 不保证其服务器之间的时间同步状态,但通常它非常好,大约几秒钟(即比 NTP 好),但有时它很糟糕,比如说,大约 10 秒的同步。我的应用程序可以处理 2-3 秒的不同步,但就用户体验而言,10 秒是不可能的。所以基本上,我选择的服务器平台并没有提供非常可靠的时间概念。

我的应用程序的客户端部分是用 JavaScript 编写的。同样,我们遇到客户也没有可靠的时间概念的情况。我没有进行任何测量,但我完全希望我的一些最终用户拥有设置为 1901、1970、2024 等的计算机时钟。所以基本上,我的客户端平台不提供可靠的时间概念。

这个问题开始让我有点抓狂。到目前为止,我能想到的最好的事情就是在 HTTP 之上实现类似 NTP 的东西(这并不像听起来那么疯狂)。这将通过在 Internet 的不同部分调试 2 或 3 台服务器来实现,并使用传统方式(PTP、NTP)来确保它们的同步至少在数百毫秒的数量级上。

然后,我将创建一个 JavaScript 类,该类使用这些 HTTP 时间源(以及可从 XMLHTTPRequest 获得的相关往返信息)实现 NTP 交集算法。

如您所知,此解决方案也很浪费时间。它不仅非常复杂,而且只解决了一半的问题,即让客户对当前时间有一个好的概念。然后我必须在服务器上妥协,要么允许客户端在他们发出请求时根据他们告诉服务器当前时间(大安全性不行,但我可以减轻一些更明显的滥用),或者让服务器向我的一个神奇的 HTTP-over-NTP 服务器发出单个请求,并希望该请求足够快地完成。

这些解决方案都很糟糕,我迷路了。

提醒:我想要一堆网络浏览器,希望多达 100 个或更多,能够同时触发一个事件。

4

5 回答 5

3

让我总结一下,以确保我理解这个问题。

您有一个具有客户端和服务器组件的应用程序。有多个服务器,每个服务器都可以为许多(数百个)客户端提供服务。服务器或多或少地相互同步;客户不是。您希望大量客户端几乎在同一时间执行相同的事件,而不管它们最初连接到哪台服务器。

假设我或多或少准确地描述了这种情况:

您是否可以让服务器为每个客户端保持某些状态(例如初始连接时间 - 服务器时间),并且当需要发生的事件的时间已知时,使用包含毫秒数的消息通知客户端在触发事件之前需要经过的起始值之后?

为了显示:

   客户端 A 在时间 t0 = 0 连接到服务器 S
   客户端 B 在时间 t1 = 120 连接到服务器 S
   服务器 S 决定一个事件需要在时间 t3 = 500 发生
   服务器 S 向 A 发送消息:
   S->A : {事件名称, 500}
   服务器 S 向 B 发送消息:
   S->B:{事件名称,380}

这根本不依赖于客户端时间;仅取决于客户在相当短的时间内(单个会话)跟踪时间的能力。

于 2009-01-11T07:04:48.777 回答
2

在我看来,您似乎需要在许多不同的地方收听来自服务器的广播事件。由于您可以接受 2-3 秒的变化,您可以将所有客户端放入长寿命的彗星式请求中,然后从服务器获得响应?在我看来,客户根本不需要以这种方式处理时间吗?

您可以使用 ajax 来执行此操作,因此您可以在等待新数据时避免任何客户端锁定。

我可能在这里完全错过了一些东西。

于 2009-01-11T06:39:02.450 回答
1

如果您可以假设时钟是合理稳定的 - 也就是说它们设置错误,但或多或​​少以正确的速率滴答作响。

让服务器从单个定义的源(例如您的服务器之一,或数据库服务器或其他东西)获取它们的偏移量。

然后让每个客户端计算它与服务器的偏移量(如果你想要很多准确性,可能会出现往返并发症)。

存储它,然后您在每个客户端上的组合偏移量以在正确的时间触发事件。

(client-time-to-trigger-event) = (scheduled-time) + (client-to-server-difference) + (server-to-reference-difference)
于 2009-01-11T09:09:29.307 回答
0

时间同步很难做到正确,我认为这是错误的方法。您需要一个事件系统,它可以在每次调度事件时通知已注册的观察者(观察者模式)。所有观察者将同时(或尽可能接近)收到通知,无需时间同步。

为了适应延迟,应该向浏览器发送事件分派的时间戳,并且它应该等待比您预期的最大延迟稍长的时间。这样,所有事件将在所有浏览器上同时触发。

于 2009-01-11T05:58:22.297 回答
0

谷歌找到了将时间定义为绝对的方法。对于物理学家和广义相对论而言,这听起来很异端:时间以不同的速度流动,具体取决于您在空间和时间、地球、宇宙中的位置......

您可能想看看 Google Spanner 数据库:http://en.wikipedia.org/wiki/Spanner_(database)

我猜它现在被谷歌使用,并将通过谷歌云平台提供。

于 2014-03-28T14:35:15.957 回答