我正在尝试同步客户端和服务器之间的时间,以便倒计时同时运行。目前客户端计时器执行速度比服务器计时器快(相当多),我不明白如何。
对于我的服务器应用程序,它是用C#编写的,并使用Web套接字与用户进行通信。服务器发送一条消息,其中包含有关计时器的数据以及剩余时间。使用数据调用以下函数;
function setTimer(secondsLeft) {
var d = new Date();
d.setSeconds(d.getSeconds() + secondsLeft);
setInterval(function() {
var time = Math.abs((new Date() - d) / 1000);
var minutes = ("00" + Math.floor(time / 60)).slice(-2);
var seconds = ("00" + Math.floor(time % 60)).slice(-2);
$(".timer-cycle").html(minutes + ":" + seconds);
$(".timer-cycle").show();
}, 1000);
}
我知道setInterval可能会导致延迟达500毫秒,但时间差异远大于此。最初在启动计时器后,它们彼此同步。但是,经过一段时间的进展后,你会开始注意到它们已经关闭了。 10分钟计时器就像1-2分钟一样。
对于获取结束时间和发送剩余时间的方法,我使用UTC偏移量使用DateTime对象。像这样;
this.Expires = DateTime.UtcNow.AddSeconds(Seconds);
this.Client.SendTimer(Seconds);
为了检查它是否已过期我有一个每1秒运行一次的计时器并在控制台上打印时间。这是命令背后的代码;
TimeSpan TimeLeft = this.Expire.Subtract(DateTime.UtcNow);
Console.Log($"[DEBUG] M: {TimeLeft.Minutes} S: {TimeLeft.Seconds}");
有没有人知道任何方式才能使它们完全同步(或至少足够接近)。我的另一个想法是每次在C#中打勾时都会发送秒数,而不是在客户端处理它,但不想发送那么多消息。
P.S。我也尝试在javascript中使用setinterval,它每次执行时都会将secondsLeft减去一,而不是转换为date对象。
这是我尝试的另一种方法;
function setTimer(secondsLeft) {
setInterval(function() {
secondsLeft -= 1;
var minutes = ("00" + Math.floor(secondsLeft / 60)).slice(-2);
var seconds = ("00" + Math.floor(secondsLeft % 60)).slice(-2);
$(".timer-cycle").html(minutes + ":" + seconds);
$(".timer-cycle").show();
}, 1000);
}
答案 0 :(得分:0)
Console.Log($"[DEBUG] M: {Time.Minutes} S: {Time.Seconds}");
应替换为:
Console.Log($"[DEBUG] M: {Math.Floor(TimeLeft.TotalMinutes)} S: {TimeLeft.Seconds}");
问题是,当您使用Time
时,您正在使用TimeLeft
变量。 Minutes属性也只能是0-59,而TotalMinutes
适用于任何值(例如超过一小时)。