mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
84 lines
3.2 KiB
JavaScript
84 lines
3.2 KiB
JavaScript
;(function(){
|
|
var Gun = (typeof window !== "undefined")? window.Gun : require('./gun');
|
|
var dam = 'nts';
|
|
var smooth = 2;
|
|
|
|
Gun.on('create', function(root){ // switch to DAM, deprecated old
|
|
Gun.log.once("nts", "gun/nts is removed deprecated old");
|
|
this.to.next(root);
|
|
return ; // stub out for now. TODO: IMPORTANT! re-add back in later.
|
|
var opt = root.opt, mesh = opt.mesh;
|
|
if(!mesh) return;
|
|
|
|
// Track connections
|
|
var connections = [];
|
|
root.on('hi', function(peer) {
|
|
this.to.next(peer);
|
|
connections.push({peer, latency: 0, offset: 0, next: 0});
|
|
});
|
|
root.on('bye', function(peer) {
|
|
this.to.next(peer);
|
|
var found = connections.find(connection => connection.peer.id == peer.id);
|
|
if (!found) return;
|
|
connections.splice(connections.indexOf(found), 1);
|
|
});
|
|
|
|
function response(msg, connection) {
|
|
var now = Date.now(); // Lack of drift intentional, provides more accurate RTT
|
|
connection.latency = (now - msg.nts[0]) / 2;
|
|
connection.offset = (msg.nts[1] + connection.latency) - (now + Gun.state.drift);
|
|
console.log(connection.offset);
|
|
Gun.state.drift += connection.offset / (connections.length + smooth);
|
|
console.log(`Update time by local: ${connection.offset} / ${connections.length + smooth}`);
|
|
}
|
|
|
|
// Handle echo & setting based on known connection latency as well
|
|
mesh.hear[dam] = function(msg, peer) {
|
|
console.log('MSG', msg);
|
|
var now = Date.now() + Gun.state.drift;
|
|
var connection = connections.find(connection => connection.peer.id == peer.id);
|
|
if (!connection) return;
|
|
if (msg.nts.length >= 2) return response(msg, connection);
|
|
mesh.say({dam, '@': msg['#'], nts: msg.nts.concat(now)}, peer);
|
|
connection.offset = msg.nts[0] + connection.latency - now;
|
|
Gun.state.drift += connection.offset / (connections.length + smooth);
|
|
console.log(`Update time by remote: ${connection.offset} / ${connections.length + smooth}`);
|
|
};
|
|
|
|
// Handle ping transmission
|
|
setTimeout(function trigger() {
|
|
console.log('TRIGGER');
|
|
if (!connections.length) return setTimeout(trigger, 100);
|
|
var now = Date.now(); // Lack of drift intentional, provides more accurate RTT & NTP reference
|
|
|
|
// Send pings
|
|
connections.forEach(function(connection) {
|
|
if (connection.next > now) return;
|
|
mesh.say({
|
|
dam,
|
|
'#': String.random(3),
|
|
nts: [now],
|
|
});
|
|
});
|
|
|
|
// Plan next round of pings
|
|
connections.forEach(function(connection) {
|
|
if (connection.next > now) return;
|
|
// https://discord.com/channels/612645357850984470/612645357850984473/755334349699809300
|
|
var delay = Math.min(2e4, Math.max(250, 150000 / Math.abs((connection.offset)||1)));
|
|
connection.next = now + delay;
|
|
});
|
|
|
|
// Plan next trigger round
|
|
// May overshoot by runtime of this function
|
|
var nextRound = Infinity;
|
|
connections.forEach(function(connection) {
|
|
nextRound = Math.min(nextRound, connection.next);
|
|
});
|
|
setTimeout(trigger, nextRound - now);
|
|
console.log(`Next sync round in ${(nextRound - now) / 1000} seconds`);
|
|
}, 1);
|
|
});
|
|
|
|
}());
|