ntpsync
Version:
Calculate the delta between local clock and NTP time, via multiple requests to various servers in the server pool
88 lines (71 loc) • 3.15 kB
JavaScript
;
var ntpClient = require('ntp-client');
var gReq = 0;
var gReqInProgress = false;
var kDefaultLocalClockService = {
Now: function Now() {
return Date.now();
}
};
var kDefaultServerCarousel = ["0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org"];
var kDefaultTimeoutLatencyMS = 500;
/**
* Creates a promise that resolves with an Date object after a successful NTP server query
* @param {Object} iNTPSingleRequestConfig: Optional Custom Parameters object
* {fLocalClockService: , fServerCarousel: ,fTimeoutLatencyMS: }:
*
* fLocalClockService: an service object with a Now() function that returns current local time in Unix milliseconds.
* Default value: kDefaultLocalClockService, which is just a wrapper for Date.now();
*
* fServerCarousel: an Array of Strings, IP Addresses of a server pool
* Default value: kDefaultServerCarousel
*
* fTimeoutLatencyMS: a timeout in milliseconds, when to bail on an NTP request
* Default value: kDefaultTimeoutLatencyMS
*
* @return {Promise} Promise that either resolves with successful Date object or an NTP server communication
* error
*/
function ntpDatePromise(iNTPSingleRequestConfig) {
var customClockService = iNTPSingleRequestConfig && iNTPSingleRequestConfig.fLocalClockService;
var customServerCarousel = iNTPSingleRequestConfig && iNTPSingleRequestConfig.fServerCarousel;
var customTimeoutLatencyMS = iNTPSingleRequestConfig && iNTPSingleRequestConfig.fTimeoutLatencyMS;
// TIME-server query via ntp: https://github.com/moonpyk/node-ntp-client
var clockService = customClockService || kDefaultLocalClockService;
var serverCarousel = customServerCarousel || kDefaultServerCarousel;
var timeoutLatency = customTimeoutLatencyMS || kDefaultTimeoutLatencyMS;
return new Promise(function (iResolveFunc, iRejectFunc) {
// See http://www.pool.ntp.org/en/ for usage information
// http://www.ntp.org/ About NTP protocol
// Or just google for "gps clock time server"
var serverAddress = serverCarousel[gReq % serverCarousel.length];
// console.log(`NTP Req ${gReq}: Pinging ${serverAddress}`);
// const startedReq = gReq;
gReq += 1;
var localClockStart = clockService.Now();
if (gReqInProgress === true) {
console.error("ERROR: Simultaneous requests running!");
iRejectFunc("ERROR: Simultaneous requests running!");
return;
}
gReqInProgress = true;
ntpClient.ntpReplyTimeout = timeoutLatency;
ntpClient.getNetworkTime(serverAddress, 123, function (iError, iDate) {
gReqInProgress = false;
if (iError) {
iRejectFunc(iError);
return;
}
var localClockNow = clockService.Now();
var latency = localClockNow - localClockStart;
iResolveFunc({
localClockNow: localClockNow,
ntpRaw: iDate.getTime(),
ntpLatency: latency
});
});
});
}
module.exports = {
ntpDatePromise: ntpDatePromise
};