首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以秒的精度计时用户任务

以秒的精度计时用户任务
EN

Stack Overflow用户
提问于 2011-07-18 01:30:36
回答 5查看 426关注 0票数 5

我正在建立一个网站,在那里我需要时间用户的任务,显示时间,因为它过去了,并跟踪他们需要多长时间来完成任务。计时器应该是精确的第二,整个任务应该需要3-4小时的顶部。

我也应该防止用户伪造完成时间(没有钱,所以这不是真正的高风险,但有一些风险)。

目前,我使用时间戳来跟踪用户开始的时间,同时初始化基于JS的计时器,当用户完成任务时,我会得到通知,并计算当前时间和开始时间戳之间的差异--这种方法不好,用户的计时器和我的时间差之间有几秒钟的差异(即我计算用户完成任务所用的时间),注意:这只在我的dev env.测试,因为我没有其他的env。还.)。

我考虑过的其他两种方法是:

  1. 完全依赖客户端计时器(即JS),以及当用户完成任务时--发送加密时间(这样,用户就不能伪造启动时间)。这似乎不太实际,因为我无法找到在客户端生成秘密密钥的方法,这将是真正的“秘密”。
  2. 完全依赖服务器端计时器,每秒钟发送“滴答”。与其他两种方法(机器,而不是人)相比,这似乎是服务器端工作的大量。例如,为每一个“滴答”访问DB以获得开始时间),我也不确定它是否会完全准确。

编辑:

下面是在算法措辞中所发生的事情:

  1. 用户启动任务-服务器发送给用户一个任务id并在db记录启动时间,客户端计时器被初始化。
  2. 用户执行任务,他的计时器正在运行..。
  3. 用户结束任务,停止定时器,并将用户的答案和任务id发送到服务器。
  4. 服务器检索开始时间(使用接收到的任务id)并计算用户完成任务所用的时间。

问题-服务器计算的时间和客户端显示的时间是不同的。

任何洞察力都会很感激的。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-07-20 23:30:51

如果我的理解是正确的话,问题是服务器和客户端的时间略有不同,而且它们总是如此。

所以我会稍微修改一下你的原始序列如下:

  1. 用户启动任务-服务器发送给用户一个任务id并在db记录启动时间,客户端计时器被初始化。
  2. 用户客户端通知服务器客户端启动时间;记录在数据库中的服务器启动时间旁边
  3. 用户执行任务,他的计时器正在运行..。
  4. 用户结束任务,停止定时器,并将用户经过的时间、答案和任务id发送到服务器。
  5. 在收到请求时,服务器记录传入的请求时间,检索开始时间,计算用户在服务器时间(开始/完成)和客户端时间中完成任务所用的时间。
  6. 服务器确保客户端值在服务器验证时间的可接受范围内,并使用客户端时间。如果客户端时间不在可接受的范围内(例如30秒),则使用服务器时间作为数字。

由于延迟、服务器负载等原因,时间上会有细微的差异,因此通过使用客户端值,它将更准确,也更安全,因为这些值是正确检查的。

要回答这个问题:

您只能有一种精确性,或者根据客户机/用户所看到的,或者根据服务器所知道的精确性。来自客户端的任何东西都可能被污染,所以必须有一个妥协的地方。您可以通过测量和偏移来最小化这一点,这样,使用服务器时间,结束差在与开始差相同的范围内,但永远不会是100%不变的。如果真的有那么多问题,那就用不太精确的方式存储时间。

如果您确实必须具有准确性和可靠性,那么唯一的方法是使用服务器时间,并通过ajax周期性地获取它以供显示,并使用本地计时器来填补实际时间和报告时间之间的滑动调整算法的空白。

票数 2
EN

Stack Overflow用户

发布于 2011-07-18 03:52:39

我想这会管用的。似乎您有同步问题,也有密码学问题。我的建议是以用户不可见的方式解决同步问题,同时仍然保持安全性。

思想:计算和显示客户端,但使用密码技术,以防止用户发送伪造的时间。只要用户的报告时间接近服务器的测量时间,只需使用用户的时间即可。否则,索赔伪造。

  1. 客户端向服务器请求任务。
  2. 服务器获取当前时间戳,并使用自己的公钥对其进行加密。这与任务(可以是纯文本)一起发送回客户端。
  3. 客户端一直工作到完成为止。蜱的地方记录在JS中。
  4. 客户机完成并将服务器发回它的答案、它重新编码的次数以及服务器首先发送的加密时间戳。
  5. 服务器对时间戳进行解密,并将时间戳与当前本地时间进行比较,以获得多个刻度。
  6. 如果服务器计算的滴答数在一定范围内(例如,10秒,为了安全起见),服务器将接受用户的报告时间。否则,它就知道时间是伪造的。

因为用户的时间被接受(只要是合理的),用户永远不知道服务器时间可能与他们报告的时间不同步。因为你跟踪的时间很长,失去几秒钟的精确性看起来并不是个问题。该方法只需要对单个时间戳进行加密,因此应该是快速的。

票数 2
EN

Stack Overflow用户

发布于 2011-07-27 13:41:23

防止欺骗的唯一方法是根本不信任客户端,而只是将服务器上的最后时间计算为在收到结果后将任务发送到客户端之前所需的时间。

这也意味着,最后一段时间必须包括一些网络传输延迟,尽管这看起来很不公平:如果您试图以某种方式补偿它们,客户总是可以假装遭受比实际更多的延迟。

但是,您可以做的是确保网络延迟不会给用户带来惊喜。以下是一种完全防止欺骗的简单方法,同时考虑到对时钟速率和网络延迟的一些温和假设,确保在提交结果时客户端显示的运行时间大致与服务器上计算的最后时间相匹配:

  1. 客户端启动定时器并从服务器请求任务。
  2. 服务器记录当前时间并将任务发送给客户端。
  3. 用户完成任务。
  4. 客户端将结果发送到服务器,并(可选)停止计时器。
  5. 服务器接受结果,并从当前时间减去在步骤2中保存的时间戳,以获得最终时间。
  6. 服务器将最后一次发送回客户端。

这里的诀窍是客户端时钟是在从服务器请求任务之前启动的。假设步骤1和步骤2与步骤4和步骤5之间的单向网络传输延迟大致相同(并且客户机和服务器时钟运行速度大致相同,即使它们不同步),在客户端计算的从步骤1到步骤4的时间应该与从步骤2到步骤5在服务器上计算的时间相匹配。

从心理学的角度来看,让客户端时钟一直运行到最后一次从服务器收到为止,这可能是个好主意。这样,当运行中的时钟被最后一次替换时,跳转很可能是向后跳的,这使得用户比如果时间稍微向前跳更快乐。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6727940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档