将两个客户端JavaScript计时器与服务器同步

时间:2022-02-18 15:25:23

I have two JavaScript countdown timers (for a game), and a MySQL table to receive data from AJAX calls from either one.

我有两个JavaScript倒计时器(用于游戏),以及一个MySQL表来接收来自任何一个AJAX调用的数据。

The process is the following:

过程如下:

  1. a client starts the timer, writes it's data1 MySQL column so that it started the timer, and a time1 column with the current timestamp (with .01s precision, from the PHP call as MySQL doesn't do that)

    客户端启动计时器,写入其data1 MySQL列,以便启动计时器,并使用当前时间戳的time1列(精度为.01s,来自PHP调用,因为MySQL不这样做)

  2. the other client (polling the server at 2s intervals) detects the change, and starts a timer, but immediately subtracts (it's a countdown timer) ctime - time1 where ctime is the timestamp from the second clients call (also given by the PHP) and time1 is the timestamp what the first client wrote when it started the timer.

    另一个客户端(以2秒间隔轮询服务器)检测到更改,并启动计时器,但立即减去(它是倒数计时器)ctime - time1,其中ctime是第二个客户端调用的时间戳(也由PHP提供)和time1是第一个客户端启动计时器时写入的时间戳。

This method is supposed to eliminate the delay caused by the 2s intervals of the polling, but regardless of if it does or not (I'm not really sure to be honest), the sync between the timers varies. Sometimes they are dead exact, sometimes they are off by up to as much as 3 seconds. (It's unreliable.)

这种方法应该消除由轮询的2s间隔引起的延迟,但无论它是否确实(我真的不确定),定时器之间的同步会有所不同。有时候它们确实是死的,有时它们最多可以消失3秒钟。 (这是不可靠的。)

Here's some of my relevant code I'm using:

这是我正在使用的一些相关代码:

var timerRunning, timeRemaining, responseTime;

function restartLocalTimer() {
    var d = new Date();
    responseTime = d.getTime()/1000;
    timerRunning = true;
    timerTick();
}

function restartSyncTimer(resp) { // resp is the AJAX response passed
    var d = new Date();
    responseTime = d.getTime()/1000 - parseFloat(resp["ctime"]) + parseFloat(resp["time"]);
    timerRunning = true;
    timerTick();
}

function timerTick() {
    d = new Date();
    timeRemaining = 20 - d.getTime()/1000 + responseTime;
    if (timerRunning) setTimeout("timerTick()",25);
}

All time values are in seconds. (Because of the database, might change to ms later.)

所有时间值都以秒为单位。 (由于数据库,以后可能会更改为ms。)

My questions are: Are there any additional (significant) delays I'm not accounting for? Is there a better way of doing this?

我的问题是:是否还有其他(重大)延误我不考虑?有更好的方法吗?

Also note: I'm open for jQuery (using it already for the AJAX calls), but don't want to use websockets.

另请注意:我对jQuery开放(使用它已经用于AJAX调用),但不想使用websockets。

2 个解决方案

#1


1  

I would take the same approach that desktop network multiplayer games take. Even during brief moments of connection disruption (e.g. "lag"), the client projects the expected trajectories during that time. In this case, you rely on a local interval, and update with the exact server time when you get the async heartbeat response.

我会采用与桌面网络多人游戏相同的方法。即使在连接中断的短暂时刻(例如“滞后”),客户端也会在该时间内投射预期的轨迹。在这种情况下,您依赖于本地间隔,并在获得异步心跳响应时使用确切的服务器时间进行更新。

#2


-1  

setTimeout and its brothers are known to be unreliable. There is another post on this: Is there a more accurate way to create a Javascript timer than setTimeout? that gives some pointers.

已知setTimeout及其兄弟不可靠。还有另外一篇文章:有没有比setTimeout更准确的方法来创建Javascript计时器?这给了一些指示。

#1


1  

I would take the same approach that desktop network multiplayer games take. Even during brief moments of connection disruption (e.g. "lag"), the client projects the expected trajectories during that time. In this case, you rely on a local interval, and update with the exact server time when you get the async heartbeat response.

我会采用与桌面网络多人游戏相同的方法。即使在连接中断的短暂时刻(例如“滞后”),客户端也会在该时间内投射预期的轨迹。在这种情况下,您依赖于本地间隔,并在获得异步心跳响应时使用确切的服务器时间进行更新。

#2


-1  

setTimeout and its brothers are known to be unreliable. There is another post on this: Is there a more accurate way to create a Javascript timer than setTimeout? that gives some pointers.

已知setTimeout及其兄弟不可靠。还有另外一篇文章:有没有比setTimeout更准确的方法来创建Javascript计时器?这给了一些指示。