2019-06-29 23:57:11 +00:00
|
|
|
import Sockette from 'sockette';
|
|
|
|
import { EventEmitter } from 'events';
|
|
|
|
|
|
|
|
export const SOCKET_EVENTS = [
|
|
|
|
'SOCKET_OPEN',
|
|
|
|
'SOCKET_RECONNECT',
|
|
|
|
'SOCKET_CLOSE',
|
|
|
|
'SOCKET_ERROR',
|
|
|
|
];
|
|
|
|
|
|
|
|
export class Websocket extends EventEmitter {
|
2019-09-25 03:20:29 +00:00
|
|
|
// The socket instance being tracked.
|
|
|
|
private socket: Sockette | null = null;
|
|
|
|
|
|
|
|
// The URL being connected to for the socket.
|
|
|
|
private url: string | null = null;
|
|
|
|
|
|
|
|
// The authentication token passed along with every request to the Daemon.
|
|
|
|
// By default this token expires every 15 minutes and must therefore be
|
|
|
|
// refreshed at a pretty continuous interval. The socket server will respond
|
|
|
|
// with "token expiring" and "token expired" events when approaching 3 minutes
|
|
|
|
// and 0 minutes to expiry.
|
|
|
|
private token: string = '';
|
|
|
|
|
|
|
|
// Connects to the websocket instance and sets the token for the initial request.
|
|
|
|
connect (url: string) {
|
|
|
|
this.url = url;
|
2019-09-25 04:22:11 +00:00
|
|
|
this.socket = new Sockette(`${this.url}?token=${this.token}`, {
|
2019-09-25 03:20:29 +00:00
|
|
|
onmessage: e => {
|
|
|
|
try {
|
|
|
|
let { event, args } = JSON.parse(e.data);
|
2019-09-25 05:05:48 +00:00
|
|
|
args ? this.emit(event, ...args) : this.emit(event);
|
2019-09-25 03:20:29 +00:00
|
|
|
} catch (ex) {
|
|
|
|
console.warn('Failed to parse incoming websocket message.', ex);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onopen: () => this.emit('SOCKET_OPEN'),
|
|
|
|
onreconnect: () => this.emit('SOCKET_RECONNECT'),
|
|
|
|
onclose: () => this.emit('SOCKET_CLOSE'),
|
|
|
|
onerror: () => this.emit('SOCKET_ERROR'),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the URL connected to for the socket.
|
|
|
|
getSocketUrl (): string | null {
|
|
|
|
return this.url;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sets the authentication token to use when sending commands back and forth
|
|
|
|
// between the websocket instance.
|
|
|
|
setToken (token: string): this {
|
|
|
|
this.token = token;
|
|
|
|
|
2019-09-28 20:09:47 +00:00
|
|
|
if (this.url) {
|
|
|
|
this.send('auth', token);
|
|
|
|
}
|
|
|
|
|
2019-09-25 03:20:29 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the token being used at the current moment.
|
|
|
|
getToken (): string {
|
|
|
|
return this.token;
|
2019-06-29 23:57:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
close (code?: number, reason?: string) {
|
2019-09-28 20:09:47 +00:00
|
|
|
this.url = null;
|
|
|
|
this.token = '';
|
2019-09-09 00:48:37 +00:00
|
|
|
this.socket && this.socket.close(code, reason);
|
2019-06-29 23:57:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
open () {
|
2019-09-09 00:48:37 +00:00
|
|
|
this.socket && this.socket.open();
|
2019-06-29 23:57:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
reconnect () {
|
2019-09-09 00:48:37 +00:00
|
|
|
this.socket && this.socket.reconnect();
|
2019-06-29 23:57:11 +00:00
|
|
|
}
|
|
|
|
|
2019-06-30 00:18:17 +00:00
|
|
|
send (event: string, payload?: string | string[]) {
|
2019-09-09 00:48:37 +00:00
|
|
|
this.socket && this.socket.send(JSON.stringify({
|
2019-09-25 03:20:29 +00:00
|
|
|
event,
|
|
|
|
args: Array.isArray(payload) ? payload : [ payload ],
|
2019-06-30 00:18:17 +00:00
|
|
|
}));
|
2019-06-29 23:57:11 +00:00
|
|
|
}
|
|
|
|
}
|