54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import {SnackReporter} from '../snack/SnackManager';
|
|
import {CurrentUser} from '../CurrentUser';
|
|
import * as config from '../config';
|
|
import {AxiosError} from 'axios';
|
|
|
|
export class WebSocketStore {
|
|
private wsActive = false;
|
|
private ws: WebSocket | null = null;
|
|
|
|
public constructor(
|
|
private readonly snack: SnackReporter,
|
|
private readonly currentUser: CurrentUser
|
|
) {}
|
|
|
|
public listen = (callback: (msg: IMessage) => void) => {
|
|
if (!this.currentUser.token() || this.wsActive) {
|
|
return;
|
|
}
|
|
this.wsActive = true;
|
|
|
|
const wsUrl = config
|
|
.get('url')
|
|
.replace('http', 'ws')
|
|
.replace('https', 'wss');
|
|
const ws = new WebSocket(wsUrl + 'stream?token=' + this.currentUser.token());
|
|
|
|
ws.onerror = (e) => {
|
|
this.wsActive = false;
|
|
console.log('WebSocket connection errored', e);
|
|
};
|
|
|
|
ws.onmessage = (data) => callback(JSON.parse(data.data));
|
|
|
|
ws.onclose = () => {
|
|
this.wsActive = false;
|
|
this.currentUser
|
|
.tryAuthenticate()
|
|
.then(() => {
|
|
this.snack('WebSocket connection closed, trying again in 30 seconds.');
|
|
setTimeout(this.listen, 30000);
|
|
})
|
|
.catch((error: AxiosError) => {
|
|
if (error && error.response && error.response.status === 401) {
|
|
this.snack('Could not authenticate with client token, logging out.');
|
|
}
|
|
});
|
|
};
|
|
|
|
this.ws = ws;
|
|
};
|
|
|
|
public close = () => this.ws && this.ws.close();
|
|
}
|