Javascript倒计时时间与服务器不同步

Javascript倒计时时间与服务器不同步,javascript,c#,datetime,timer,synchronization,Javascript,C#,Datetime,Timer,Synchronization,我正在尝试同步客户端和服务器之间的时间,以便同时进行倒计时。目前,客户机计时器的执行速度比服务器计时器快(相当多),我不明白怎么做 对于我的服务器应用程序,它是用C#编写的,并使用web套接字与用户通信。服务器发送一条消息,其中包含有关计时器和剩余时间的数据。以下函数是使用数据调用的函数 function setTimer(secondsLeft) { var d = new Date(); d.setSeconds(d.getSeconds() + secondsLeft); s

我正在尝试同步客户端和服务器之间的时间,以便同时进行倒计时。目前,客户机计时器的执行速度比服务器计时器快(相当多),我不明白怎么做

对于我的服务器应用程序,它是用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#的形式滴答作响时发送剩余的秒数,而不是在客户机上进行处理,但不想发送那么多消息。

另外,我还尝试在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);
}
应替换为:

Console.Log($"[DEBUG] M: {Math.Floor(TimeLeft.TotalMinutes)} S: {TimeLeft.Seconds}");

问题是,当您应该使用
TimeLeft
时,您正在使用
Time
变量。此外,Minutes属性只能从0到59,而
TotalMinutes
将适用于任何值(例如超过一小时)。

如果您希望与其他值完全相同,则应继续将您的时间信息从服务器发送到客户端。但是,如果您不想继续发送时间信息,只需从服务器发送小时、分钟、秒,然后在客户端将它们放入
setInterval()
中,每1000毫秒重复一次,而不是计时。(例如,当秒变为60时增加分钟,并将其重置为0)在时间到期后,C#中不会发生事件。例如,如果用户正在执行任务,他们最多有15分钟完成任务。所以他们可以看到左下角的时间。javascript的运行速度一直很快(虽然它与我的电脑时钟同步)。在几个不同的机器上的几个不同的客户端上进行测试,结果都是一样的。。在实际服务器上使用客户端时,计时器是同步的。但是如果我在我的电脑上使用它们,它们就不同步了。如果不看到整个类都包含
TimeLeft
变量,我就不能给你任何有意义的建议。我的错是,我在检查时确实改变了这一点,但仍然是同一个问题。就好像计时器运行得比较慢,不知道为什么请用您当前的实际代码更新您的帖子。根据我上面的示例,您应该修复
TimeLeft.Minutes
。它也以秒为单位,而不仅仅是分钟。而且这不仅仅是一秒钟,所以将秒数取整是行不通的。谢谢
Console.Log($"[DEBUG] M: {Math.Floor(TimeLeft.TotalMinutes)} S: {TimeLeft.Seconds}");