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>