Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronise two client side JavaScript timers with server

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

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)

  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.

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.)

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.)

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.

like image 521
Gabor Magyar Avatar asked Mar 05 '13 19:03

Gabor Magyar


1 Answers

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.

like image 193
landons Avatar answered Oct 18 '22 16:10

landons