dist/bundle/clock.js
/**
* Clock handles synchronizing the local time against the server, adjusting
* for any client-size clock skew.
*/
export class Clock {
constructor(socket) {
this.socket = socket;
this.delta = 0;
this.awaiting = new Promise(resolve => {
socket.once('interactivePacket', () => {
resolve(this.sync());
});
});
}
/**
* Adjusts a timestamp given by the remote server to the local timestamp.
* @param {number} timestamp
* @returns {Promise.<number>}
*/
remoteToLocal(timestamp) {
return this.awaiting.then(() => timestamp - this.delta);
}
/**
* Adjusts a timestamp created locally to the one on the remote server.
* @param {number} timestamp
* @returns {Promise.<number>}
*/
localToRemote(timestamp) {
return this.awaiting.then(() => timestamp + this.delta);
}
/**
* sync runs a quick clock synchronization against the server. Recursive
* calls itself, with the remaining samples to take as well as samples
* of the drift between the local and server clock.
* @private
*/
sync(remaining = 3, deltaSamples = []) {
const start = Date.now();
return (this.socket
.call('getTime', {})
.then(({ time }) => {
const now = Date.now();
// To get the clock delta, add the latency to the time the server
// said it had back then, and compare it with the current time.
deltaSamples.push(time + (now - start) / 2 - now);
if (remaining > 0) {
return this.sync(remaining - 1, deltaSamples);
}
this.delta = deltaSamples.sort()[Math.floor(deltaSamples.length / 2)];
return undefined;
})
.catch(() => undefined));
}
}