ntp-clientとsocket.ioを使ってみた。
学習を始めたJavaScriptのクラス使い方も試してみた。
以下に示す例はnode.jsでntp-clientを使用して自コンピュータ時刻(サーバ側)とntpサーバーの時刻の差を6分置きに取得する。
そして10秒置きに自コンピュータ時刻(サーバ側)を取得してオフセットを足して,socket.ioを通して送信する。
サンプルにしては長いものになっている。
まずアプリのスタートポイントの(本体)serv.js
const GetNtp = require('./GetNtp') var getNtp = new GetNtp(); var ntpServer = 'ntp.nict.jp'; var task = new Promise(function(resolve, reject) { getNtp.getNetworkTime(ntpServer, 123, resolve, reject); }) task.then(function(value) { // 6分置きにオフセットmsを更新 setInterval(function () { getNtp.getNetworkTime(ntpServer, 123); }, 360000); // 10秒置きに時刻を送信 setInterval(function() { var value = new Date(); value = new Date(value.valueOf() + getNtp.timeOffset); socketIOHandler.io.sockets.emit('date', {'date': value}); }, 10000); }); var SocketIOHandler = require('./SocketIOHandler'); var socketIOHandler = new SocketIOHandler(8081, getNtp); socketIOHandler.start();
クラスの勉強中につきGetNtpというクラス風のオブジェクトを作成するGetNtp.js
var GetNtp = function() { this.ntpClient = require('ntp-client'); this.last = null; this.timeOffset = 0; } GetNtp.prototype.getNetworkTime = function(uri, port, resolve, reject) { var before = new Date(); this.ntpClient.getNetworkTime(uri, port, (err, date)=> { if(err) { console.error(err); if (typeof reject !== "undefined") reject(); return; } var after = new Date(); var computerDate = (before.valueOf() + after.valueOf()) / 2.0; this.timeOffset = date.valueOf() - computerDate.valueOf(); // コンピュータ時刻が進んでいたら負 console.log('Time Offset Updated: ' + this.timeOffset.toFixed(1) + " ms"); this.last = date; if (typeof resolve !== "undefined") resolve(date) }); } module.exports = GetNtp
同様にクラス風オブジェクトを作成するSocketIOHandler.js
var SocketIOHandler = function(port, getNtp) { this.getNtp = getNtp; this.fs = require('fs'); this.handler = function(req, res) { this.fs.readFile(__dirname + '/index.html', function (err, data) { if (err) { res.writeHead(500); return res.end('Error loading index.html'); } res.writeHead(200); res.end(data); }); }.bind(this); this.app = require('http').createServer(this.handler); this.io = require('socket.io')(this.app); this.start = () => { this.app.listen(port); } this.io.on('connection', (socket) => { socket.emit('connected', { hello: 'world' }); { var value = new Date(); value = new Date(value.valueOf() + this.getNtp.timeOffset); socket.emit('date', {'date': value}); } socket.on('test', function (data) { console.log(data); }); }); } module.exports = SocketIOHandler;
クライアント側のコードindex.html。(httpでクライアントに読ませて使用する)
<html> <head> <title>Sample App</title> <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script> </head> <body> <div id="test"></div> <script src="/socket.io/socket.io.js"></script> <script> var socket = io('http://localhost:8081'); socket.on('connected', function (data) { console.log(data); socket.emit('test', { value: 'data' }); }); socket.on('date', function(data) { console.log(data); $('#test').html(data.date); }); </script> </body> </html>