Skip to content

Instantly share code, notes, and snippets.

@kigiri
Last active April 6, 2020 09:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kigiri/2baa90c1959e8d53dc05306334cba46e to your computer and use it in GitHub Desktop.
Save kigiri/2baa90c1959e8d53dc05306334cba46e to your computer and use it in GitHub Desktop.
Synchronise time across clients & server
const functions = require('firebase-functions')
const cors = res => {
res.setHeader('Timing-Allow-Origin', 'https://nice-timer.web.app')
res.setHeader('Access-Control-Allow-Origin', 'https://nice-timer.web.app')
res.setHeader('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS')
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
return res
}
exports.now = functions.https.onRequest((_, res) => cors(res).send(`${Date.now()}`))
const now = (() => {
let offset = Number(localStorage.timeOffset) || 0
let precision = Number(localStorage.timePrecision) || Infinity
const calcDiff = async iteration => {
const seed = Math.random().toString(36).slice(2)
const url = `https://us-central1-nice-timer.cloudfunctions.net/now?no-cache=${seed}`
const res = await fetch(url)
const unixtime = Number(await res.text())
if (!unixtime || req.status !== 200) return
const resource = performance
.getEntriesByType("resource")
.find(r => r.name === url)
const diff = resource.responseStart - resource.requestStart
const fromCache = resource.transferSize == null // not set in safari, fallback to timings
? diff < 25 // usually firebase is fairly slow, so something too fast will be discarded
: resource.transferSize === 0
if (fromCache || precision < diff || unixtime > 900000) return // we also discard more than 15min diff
localStorage.timePrecision = precision = diff
localStorage.timeOffset = offset = unixtime + Math.floor(diff / 2) - end
if (iteration < 3) return setTimeout(calcDiff, 150, iteration + 1)
}
calcDiff(1)
return () => offset + Date.now()
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment