Skip to content

Commit a516c23

Browse files
committed
fix network change + refactor - closes #2
1 parent d463103 commit a516c23

File tree

4 files changed

+285
-1048
lines changed

4 files changed

+285
-1048
lines changed

main.js

+12-36
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,10 @@
1-
const timers = require('timers');
21
const path = require('path');
3-
const dns = require('dns');
4-
const Ping = require('ping-lite');
5-
const { forever, timeout, parallel, waterfall } = require('async');
6-
const { app, dialog, BrowserWindow, Tray, Menu } = require('electron');
2+
const networkStatus = require('./network-status');
3+
const { app, BrowserWindow, Tray, Menu } = require('electron');
4+
const timeoutMs = 2000;
75

8-
const dnsLatency = (host, callback) => {
9-
const dnsStartMs = +(new Date);
10-
dns.resolve(host, err => {
11-
if (err) return callback(err);
12-
callback(null, +(new Date) - dnsStartMs);
13-
});
14-
}
15-
16-
const pingLatency = (ip, callback) => {
17-
const ping = new Ping(ip);
18-
ping.send((err, latencyMs) => {
19-
if (err) return callback(err);
20-
callback(null, Math.round(latencyMs));
21-
});
22-
}
23-
24-
let mainWindow;
256
app.on('ready', () => {
26-
mainWindow = new BrowserWindow({show: false});
7+
new BrowserWindow({show: false});
278
if (app.dock) app.dock.hide();
289

2910
const tray = new Tray(path.join(app.getAppPath(), 'icon.png'));
@@ -39,17 +20,12 @@ app.on('ready', () => {
3920
let title = `.../...ms`;
4021
tray.setTitle(title);
4122

42-
const refreshLatency = (check, arg, timeoutMs, titleRegex) =>
43-
() => setInterval(() => {
44-
timeout(check, timeoutMs)(arg, (err, latency) => {
45-
title = title.replace(titleRegex, latency || '...');
46-
tray.setTitle(title);
47-
})
48-
}, timeoutMs + 100);
49-
50-
parallel([
51-
refreshLatency(dnsLatency, 'google.com', 2000, /[\d\.]+(?=\/)/),
52-
refreshLatency(pingLatency, '8.8.8.8', 2000, /[\d\.]+(?=ms)/),
53-
]);
54-
23+
networkStatus({
24+
timeoutMs: 2000,
25+
intervalMs: 2000,
26+
hostname: 'google.com',
27+
address: '8.8.8.8'
28+
}).on('latencies', ({dns, ping}) =>
29+
tray.setTitle(`${dns || '...'}/${ping || '...'}ms`)
30+
);
5531
});

network-status.js

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const timers = require('timers');
2+
const EventEmitter = require('events');
3+
const Ping = require('ping-lite');
4+
const dns = require('dns-socket');
5+
const resolv = require('resolv');
6+
7+
const dnsLatency = (hostname, timeout) =>
8+
new Promise((resolve, reject) => {
9+
var socket = dns({ timeout });
10+
const nameserver = resolv().nameserver[0];
11+
const query = { questions: [{ type: 'A', name: hostname }] };
12+
const dnsStartMs = +(new Date());
13+
socket.query(query, 53, nameserver, error =>
14+
error ? reject(error) : resolve(+(new Date()) - dnsStartMs));
15+
}
16+
);
17+
18+
const pingLatency = (address) =>
19+
new Promise((resolve, reject) =>
20+
new Ping(address).send((error, latencyMs) =>
21+
error ? reject(error) : resolve(Math.round(latencyMs))
22+
)
23+
);
24+
25+
const timeout = (promise, timeoutMs) => {
26+
let timer = null;
27+
const clearTimeout = () => timers.clearTimeout(timer);
28+
return Promise.race([
29+
promise,
30+
new Promise((resolve, reject) => {
31+
timer = setTimeout(() => reject(new Error('timed out')), timeoutMs);
32+
})
33+
])
34+
.then(value => { clearTimeout(); return value; })
35+
.catch(error => { clearTimeout(); throw error; });
36+
};
37+
38+
const allIgnoreErrors = (promises) => Promise.all(
39+
promises.map(promise => promise.catch(() => null))
40+
);
41+
42+
const checkLatencies = ({ hostname, address, timeoutMs }) =>
43+
allIgnoreErrors([
44+
dnsLatency(hostname, timeoutMs).catch(() => null),
45+
timeout(pingLatency(address), timeoutMs).catch(() => null)
46+
]);
47+
48+
const networkStatus = (options) => {
49+
const latencies = new EventEmitter();
50+
setInterval(() => checkLatencies(options)
51+
.then(([dns, ping]) =>
52+
latencies.emit('latencies', { dns, ping })
53+
)
54+
, options.intervalMs);
55+
return latencies;
56+
};
57+
58+
if (require.main === module) {
59+
networkStatus({
60+
timeoutMs: 2000,
61+
intervalMs: 2000,
62+
hostname: 'google.com',
63+
address: '8.8.8.8'
64+
}).on('latencies', console.log);
65+
}
66+
67+
module.exports = networkStatus;

package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"name": "TrayPing",
33
"version": "3.0.0",
4-
"description": "tray application showing google.com ping times",
4+
"description": "tray application showing DNS/ping latency",
55
"dependencies": {
6-
"async": "^2.1.4",
7-
"ping-lite": "^1.0.2"
6+
"dns-socket": "^1.6.1",
7+
"ping-lite": "^1.0.2",
8+
"resolv": "^1.0.0"
89
},
910
"devDependencies": {
1011
"electron": "^1.4.13",

0 commit comments

Comments
 (0)