如题目,当网站有竞拍的活动需要倒计时,怎样在不同客户端完全同步倒计时?
取服务器时间,以它为标准在客户端用js进行倒计时,间隔一定时间再次取服务器时间对客户端倒计时进行校对,这样虽然能减少误差,但不能避免误差,有没有更好的办法?

解决方案 »

  1.   

    这种情况是不是只有B/S有,C/S应该不会有这种问题吧?
      

  2.   

    如果用flash做倒计时,相比之下误差会不会更大?
      

  3.   

    严格来说,“避免误差”是不可能的,只能尽量减小误差。你说的“间隔一定时间再次取服务器时间对客户端倒计时进行校对”,这个办法解决的是“客户端时钟不准”的问题。其实这个问题一般来说不会很严重,就算你的 js 在客户端浏览器上跑一个小时,也未必能差出一秒。相对来说,更严重的问题是如何让所有客户端都能得到“相同的时间基点”。由于不同浏览器的网络环境差异,它们从服务器获取页面内容所需的时间是不同的,所以在客户端用 js 进行倒计时的起点也无法在事实上跟服务器保持一致。几秒钟的差异可能在特定的应用场景就是很致命的了。关于这个问题,如果你真的要求很严格的话,可以参考 NTP - Network Time Protocol,借用它的一些算法思想。
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  4.   

    学习了,关于NTP第一次接触,竟然还有个这协议,非常感谢
      

  5.   

    看了一遍,是纯理论的,具体该怎么应用NTP呢?
      

  6.   


    你试一试当一个页面有一些操作如alert时候就知道了,时间会停止
      

  7.   

    重要的其实不是什么客户端与用户端时间差问题,而起也和客户端与服务端时间差没关系,主要就是一些alert等操作影响时间的计算,楼主可以试着减少弹出框
      

  8.   

    秒级误差在B/S结构下基本很难解决!
    除此之外,很多时候客户端的时间差分钟、小时、甚至年月日完全不对的,可以通过下面方式解决:var d = new Date();
    d.setTime(<?php echo time()?>000);[/code]
      

  9.   

    可以用 server push 技术实现。
      

  10.   


    我想你说的可能是类似这种情况:js 设置了每隔一秒钟触发一次,根据当前机器的时间来改写时间显示。那么,当有 alert() 的时候,事件响应就被跳过了(就是你说的“时间停止”)。你说的这个是对的,所以应该考虑尽量避免类似 alert() 这种会阻塞事件响应的用法。但是,结合楼主这个应用背景,我认为他的问题要点不在这里,要点在于所有的客户端要显示一致的时间。比如秒杀,如果一个用户他的机器时钟不准,比标准时间慢几分钟,那好了,等他下手的时候,活动早结束了 :D所以,关键是时间显示不能使用客户端的时钟,而要使用服务器的时钟,只用客户端的时钟来处理增量显示。这样的话,每个客户端上显示的时间基本就是相同的了,差异就在于各自机器从服务器上获取网页所耗的时间长短不一样,网速越慢的机器显示出来的时间比实际的服务器时间越滞后。如果对每个客户端上所显示时间的一致性要求更严格的话,就要想办法消除网络延迟导致的误差。所以我前面建议参考 NTP 的算法,不过说归说,我也没自己实现过。
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  11.   


    你说B/S服务器不能主动向客户端推送数据,那腾讯 webqq 是如何实现的?
      

  12.   

    web 服务器可以“主动”向客户端浏览器“推送”信息,用的是一种俗称“HTTP 长连接”的技术,可以搜索 "comet server" 找到相关资料。这种“推送”可以让服务器把信息“及时”地发送给客户端。但“及时”并不是“不需要时间”,数据传输的网络延迟该是多少还是多少,所以在楼主这个应用场景里,“推送”并不能解决客户端跟服务器端时钟差异的问题,当然也就不能解决不同客户端之间时间显示不一致的问题。
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  13.   

    NTP 我也没真正研究过,就按照我最粗糙的理解,先给一个消减延迟误差的思路吧:1. 客户端浏览器向服务器发一个请求(就说是 AJAX 的吧),当时客户端时钟为 t1。2. 服务器收到请求并处理,当时服务器端时钟为 T1。3. 客户端浏览器收到响应结果,当时客户端时钟为 t2。然后,假设这个 HTTP 请求在上行传输和下行传输所消耗的时间是一样的(注意,这只是一个假设),那么,当客户端在收到响应的那个时刻,就可以认为服务器时钟为 T2 = T1 + (t2 - t1) / 2。把这个 T2 显示给用户,并启动间隔为 1 秒的定时器,每次根据当时的客户端时钟 tx 重新计算 Tx = T2 + (tx - t2)。回头再看那个假设,如果事实如此的话,当然这个算法就完美了。可惜,这个是没准的。所以,就凑合着用吧,聊胜于无,hehe
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  14.   

    你的意思是只用服务器时间和setinterval函数来实现,客户端时间不参与?