Socket.io同步倒计时?

时间:2016-12-25 10:52:14

标签: javascript node.js asynchronous socket.io

在我的服务器端脚本上,我同时调用两个emits,看起来像这样。

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

一个是为了对手而另一个是为了自己。

我的问题是加载数据时,我的Android应用中的两个玩家都会显示倒计时。 对我而言重要的是,他们在屏幕上看到相同的数字并同时播放音乐。

我打开所有提示。

4 个答案:

答案 0 :(得分: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/

希望这有帮助。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我可以给你一些像波纹管的东西,但我没有经过测试。 此解决方案包含以下步骤:

  1. 同步clientserver的计时器。所有用户都具有相同的difference服务器计时器。
  2. 为所需的response/request客户提供时间并找到服务器时间differences
  3. smallest视为将开始的第一次倒计时。
  4. 对于每个response(socket) difference中减去<{em> smallest,并在等待time之后让客户端计数器启动。
  5. 在响应数据中获取0的客户端将立即启动。 您可能会遇到的主要问题是broadcast方法,如果您认为此解决方案有用,则无法使用该方法。 This is a post may will help you.

答案 3 :(得分:0)

在发出消息中添加时间。 让我们说歌曲是一个具有{"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个客户来自同一时区时,这种方法很有效,因此您需要&#34;时间转换器&#34;如果您严格需要相同的数字,请检查时间是否合适。

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