forked from deriv-com/SmartCharts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNetworkMonitor.ts
80 lines (78 loc) · 3.04 KB
/
NetworkMonitor.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { PendingPromise } from '@deriv-com/smartcharts';
import { PingResponse } from '@deriv/api-types';
import { TNetworkConfig, TRequestAPI } from 'src/types';
// eslint-disable-line import/no-extraneous-dependencies,import/no-unresolved
type TOnStatusUpdated = (config: TNetworkConfig, is_online: boolean) => void;
class NetworkMonitor {
static _instance: NetworkMonitor;
_requestAPI?: TRequestAPI | null;
getTimeInterval?: ReturnType<typeof setInterval>;
onStatusUpdated?: TOnStatusUpdated;
status_config = {
online: { class: 'online', tooltip: t.translate('Online') },
offline: { class: 'offline', tooltip: t.translate('Offline') },
blinking: { class: 'blinker', tooltip: t.translate('Connecting to server') },
};
last_status?: string;
last_is_online?: boolean;
statusStarted = false;
statusStartedPromise = PendingPromise<void, void>();
setNetworkStatus = (status: string) => {
const is_online = this.isOnline();
if (status !== this.last_status || is_online !== this.last_is_online) {
this.last_status = status;
this.last_is_online = is_online;
if (typeof this.onStatusUpdated === 'function') {
const status_config = this.status_config;
this.onStatusUpdated(this.status_config[status as keyof typeof status_config], is_online);
}
}
};
isOnline = () => navigator.onLine;
async init(requestAPI?: TRequestAPI | null, updatedCallback?: TOnStatusUpdated) {
this._requestAPI = requestAPI;
this.onStatusUpdated = updatedCallback;
if ('onLine' in navigator) {
window.addEventListener('online', () => {
this.setNetworkStatus('blinking');
this.establishConnection();
});
window.addEventListener('offline', () => this.setNetworkStatus('offline'));
}
this.setNetworkStatus(this.isOnline() ? 'blinking' : 'offline');
return this.establishConnection();
}
async establishConnection() {
if (!this.statusStarted && this.isOnline()) {
this.statusStarted = true;
clearInterval(this.getTimeInterval as NodeJS.Timeout);
await this.requestPing();
this.getTimeInterval = setInterval(this.requestPing.bind(this), 30000);
} else {
return this.statusStartedPromise;
}
}
async requestPing() {
await this._requestAPI?.({ ping: 1 }).then(this._statusResponse);
this.statusStartedPromise.resolve();
}
_statusResponse = (response: PingResponse) => {
if (response.error) {
this.statusStarted = false;
}
if (!this.statusStarted) {
this.init();
return;
}
if (response.ping === 'pong') {
this.setNetworkStatus('online');
}
};
static getInstance() {
if (!this._instance) {
this._instance = new NetworkMonitor();
}
return this._instance;
}
}
export default NetworkMonitor;