node-ntp-sync icon indicating copy to clipboard operation
node-ntp-sync copied to clipboard

How to use in browser?

Open frederikheld opened this issue 3 years ago • 9 comments

Hey @luk3skyw4lker,

thank you for your great work. I'm looking for high precision time synchronization with JS and this package seems to do exactly this.

However, I was not able to get the client running in the browser. When packing it with Webpack it throws dependency errors. I also tried to serve 'node_modules/ntp-time/src/client.js' through express as a static file but it didn't work either.

Can you please help me to get the client running in the browser?

Thanks in advance Frederik

frederikheld avatar Aug 27 '22 20:08 frederikheld

What are the dependency issues? The package doesn't have any production dependencies, only jest to run tests. I didn't use any other library to build it.

luk3skyw4lker avatar Aug 27 '22 20:08 luk3skyw4lker

Thanks for your quick answer :-) The issue is the missing dgram package for udp connections. I did some more research and there seem to be several issues with that:

  • First of all dgram was previously a separate npm package but is now part of core NodeJS (which is not available in the browser) (source 1, source 2)
  • Webpack <5 did do automatic polyfills for core NodeJS packages but Webpack 5 doesn't. The solution would be to use Webpack <5 (source)
  • But this wouldn't help either as browsers can't do UDP :-| (source)

So this seems to be an unsolvable issue :-P

I actually chose your package for its combination of NTP and UDP because I hoped that this would have the least latency and highest precision of all available time sync packages. Websockets seem to be low latency as well. Would it be possible to use ntp-time with websockets?

frederikheld avatar Aug 27 '22 21:08 frederikheld

I don't think that this would be possible, since the communication between NTP servers is done by UDP protocol. But even if you had a server that accepts NTP requests by websockets (which is definitely not the standard), this library has only implemented with UDP packages.

luk3skyw4lker avatar Aug 27 '22 23:08 luk3skyw4lker

Edit: okay nevermind, it's just another Node module that is not available in the browser :-P

Thanks for clarification. I forked your repo and started to replace dgram with socket.io. I'm getting pretty close but there's one thing I can't wrap my head around:

The client gives me:

Uncaught TypeError: data.slice(...).readFloatBE is not a function
    at NTPPacket.parse (packet.js:81:1)
    at parse (websocketClient.js:16:1)
    at Socket.<anonymous> (websocketClient.js:103:1)
    at Emitter.emit (index.mjs:136:1)
    at Socket.emitEvent (socket.js:294:1)
    at Socket.onevent (socket.js:281:1)
    at Socket.onpacket (socket.js:249:1)
    at Emitter.emit (index.mjs:136:1)
    at Manager.ondecoded (manager.js:233:1)
    at Emitter.emit (index.mjs:136:1)

Line 81 in packet.js looks like this:

		packet.rootDelay = data.slice(4, 8).readFloatBE(0) / 2 ** 16;

I did not change anything in packet.js. data that goes into NTPPacket.parse() is an ArrayBuffer with the proper length of 48.

The message that goes into NTPPacket.bufferize() looks like this:

NTPPacket {
  mode: 3,
  leap: 0,
  version: 3,
  stratum: 2,
  poll: 10,
  precision: 0,
  rootDelay: 0,
  rootDispersion: 0,
  referenceId: <Buffer 00 00 00 00>,
  referenceTimestamp: 1661724417,
  originateTimestamp: 2208988800,
  rxTimestamp: 1661724422,
  txTimestamp: 2208988800
}

What am I doing wrong here?

frederikheld avatar Aug 28 '22 22:08 frederikheld

You should check the return of the data.slice to see if it's being returned as a instance of the Buffer class, if it's not, you should find some other way of reading the floating bytes out of it.

If you want to, you can create a SocketNTPServer class and make a PR to this repository, I would be glad to review the code and release it into NPM.

luk3skyw4lker avatar Aug 29 '22 12:08 luk3skyw4lker

Besides, the input of the parse function shouldn't be a ArrayBuffer, it should be a Buffer, they're different classes.

luk3skyw4lker avatar Aug 29 '22 15:08 luk3skyw4lker

Hi. Any update on this? Can WebSockets actually be leveraged to function with generic NTP servers?

acies avatar Oct 12 '22 10:10 acies

I developed my own package that is syncing via WebSockets (but using a simpler protocol than NTP). It's closed source though, as it's gonna be the USP of the service I'm working on ... sorry :-P

frederikheld avatar Oct 17 '22 14:10 frederikheld

I can't work in the browser compatibility now, but if anyone has the time to do it I would be glad to review and help. I'm gonna leave this issue open for future references and if nobody comes to it, I'll do it myself when I manage to make some time.

Sorry for being unavailable for it now!

luk3skyw4lker avatar Jan 10 '23 16:01 luk3skyw4lker