【问题标题】:Socket.io countdown synchronously? [duplicate]Socket.io 同步倒计时? [复制]
【发布时间】:2016-12-25 10:52:14
【问题描述】:

在我的服务器上,我同时调用两个发射,看起来像这样。

if (songs.length > 0) {
    socket.emit('data loaded', songs);
    socket.broadcast.to(opponent).emit('data loaded', songs);
}

一个给对手,另一个给自己

加载数据后,我的 Android 应用上的两个玩家都会出现倒计时。对我来说,重要他们在屏幕上同时看到相同的数字。准确地说,它应该同步运行。我该怎么做?

【问题讨论】:

  • 也许让客户端发回一个令牌,表示他们在倒计时的位置,并且只有当它们具有相同的值时才发送消息倒计时?不幸的是,如果您考虑到每个用户的延迟,我认为这可能是唯一的方法。
  • @SamJudge 你能用代码示例解释更多吗?
  • 您需要精确到什么程度?用户之间的距离有多远,用户和服务器之间的延迟是多少?使用上面的代码,两个用户应该非常接近同步,但这实际上取决于您对“同步”的定义......
  • 将客户端时钟同步到服务器,发送带有响应的未来时间戳,允许一些 MS 延迟。当客户端到达时间时,触发事件。届时两个玩家都应该拥有有效载荷(msLag *2)

标签: node.js socket.io synchronized


【解决方案1】:

就 js 计时器而言,这将是一个很小的差异。我们可以通过减少延迟时间来减少时间差异,以及来自服务器的请求和响应时间之间的差异。

function syncTime() {
console.log("syncing time")
var currentTime = (new Date).getTime();

res.open('HEAD', document.location, false);
res.onreadystatechange = function()
{
    var latency = (new Date).getTime() - currentTime;
    var timestring = res.getResponseHeader("DATE");
    systemtime = new Date(timestring);
    systemtime.setMilliseconds(systemtime.getMilliseconds() + (latency / 2))
};
res.send(null);
}

需要计算发送请求和取回响应之间经过的时间,将该值除以 2。这样就可以得到一个粗略的延迟值。如果将其添加到服务器的时间值中,您将更接近真实的服务器时间(差异以微秒为单位)

参考:http://ejohn.org/blog/accuracy-of-javascript-time/

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我已经申请了,但我遇到了同样的问题。在那种情况下,我解决了将时间控制权留给服务器的问题。服务器发送给客户端,客户端增加时间。也许在您的情况下,您可能会遇到连接问题。如果问题存在,您可以让客户自己增加时间,有时会发送带有正确时间的刻度以进行同步。

    【讨论】:

      【解决方案3】:

      我可以给你类似下面的东西,但我没有经过测试。 此解决方案有以下步骤:

      1. 同步clientserver 的计时器。所有用户都有相同的difference 和服务器计时器。
      2. 对于所需的response/request 获取客户端时间并找到differences 和服务器时间。
      3. smallest 视为将开始的第一个倒计时。
      4. 对于每个response(socket) 减去 differencesmallest 并让客户端计数器在等待与此time 一样多后启动。

      在响应数据中获得0 的客户端将立即启动。 您可能会遇到的主要问题是broadcast 方法,如果您认为此解决方案会有所帮助,则不能使用该方法。 This is a post may will help you.

      【讨论】:

        【解决方案4】:

        在发出消息中添加时间。 假设歌曲是一个带有
        {"time" : timeString, "songs" : songsList}.

        的对象。

        如果我们认为设备时间是正确的,您可以计算信息传播所需的时间,然后只需使用服务器计时器作为主要计算器。

        客户端会得到应该开始倒计时的时间:

        var start = false;
        var startTime = 0;
        var myTime = new Date().getMilliseconds();
        var delay = 1000 - myTime;
        
        setTimeout(function(){
            intervalID = setInterval(function(){
                myTime = new Date().getTime();
                //console.log(myTime); to check if there is round number of milliseconds
                if (startTime <= myTime && start = true) {startCountdown();}
            }, 100); //put 1000 to check every second if second is round 
                     //or put 100 or 200 is second is not round
        }, delay);
        
        socket.on('data loaded', data){        
            startTime = data.time;
            start = true;
        }
        
        function startCountdown(){
            //your time countdown
        }
        

        当 2 个客户来自同一时间区域时,这可以正常工作,因此如果您严格需要相同的数字,您将需要“时间转换器”来检查由于时差而导致的时间是否合适。

        倒计时结束后你应该clearInterval(intervalID);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-11-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-18
          • 2017-12-15
          相关资源
          最近更新 更多