refactor webscoket reconnection logic.

This commit is contained in:
Miroslav Šedivý 2021-02-08 19:14:39 +01:00
parent 85a3f4fd9d
commit 1ab1953dea
2 changed files with 39 additions and 17 deletions

View File

@ -1,7 +1,9 @@
import EventEmitter from 'eventemitter3' import EventEmitter from 'eventemitter3'
import { Logger } from '../utils/logger' import { Logger } from '../utils/logger'
export const timeout = 15000 export const connTimeout = 15000
export const reconnTimeout = 1000
export const reconnMultiplier = 1.2
export interface NekoWebSocketEvents { export interface NekoWebSocketEvents {
connecting: () => void connecting: () => void
@ -12,10 +14,14 @@ export interface NekoWebSocketEvents {
export class NekoWebSocket extends EventEmitter<NekoWebSocketEvents> { export class NekoWebSocket extends EventEmitter<NekoWebSocketEvents> {
private _ws?: WebSocket private _ws?: WebSocket
private _timeout?: NodeJS.Timeout private _connTimer?: NodeJS.Timeout
private _log: Logger private _log: Logger
private _url: string private _url: string
// reconnection
private _reconTimer?: NodeJS.Timeout
private _reconnTimeout: number = reconnTimeout
constructor() { constructor() {
super() super()
@ -57,14 +63,14 @@ export class NekoWebSocket extends EventEmitter<NekoWebSocketEvents> {
this._ws.onerror = this.onError.bind(this) this._ws.onerror = this.onError.bind(this)
this._ws.onmessage = this.onMessage.bind(this) this._ws.onmessage = this.onMessage.bind(this)
this._timeout = setTimeout(this.onTimeout.bind(this), timeout) this._connTimer = setTimeout(this.onTimeout.bind(this), connTimeout)
} }
public disconnect(reason?: Error) { public disconnect(reason?: Error) {
this.emit('disconnected', reason) this.emit('disconnected', reason)
if (this._timeout) { if (this._connTimer) {
clearTimeout(this._timeout) clearTimeout(this._connTimer)
} }
if (typeof this._ws !== 'undefined') { if (typeof this._ws !== 'undefined') {
@ -92,6 +98,14 @@ export class NekoWebSocket extends EventEmitter<NekoWebSocketEvents> {
this._ws!.send(JSON.stringify({ event, ...payload })) this._ws!.send(JSON.stringify({ event, ...payload }))
} }
private tryReconnect() {
if (this._reconTimer) {
clearTimeout(this._reconTimer)
}
this._reconTimer = setTimeout(this.onReconnect.bind(this), this._reconnTimeout)
}
private onMessage(e: MessageEvent) { private onMessage(e: MessageEvent) {
const { event, ...payload } = JSON.parse(e.data) const { event, ...payload } = JSON.parse(e.data)
@ -100,8 +114,12 @@ export class NekoWebSocket extends EventEmitter<NekoWebSocketEvents> {
} }
private onConnected() { private onConnected() {
if (this._timeout) { if (this._connTimer) {
clearTimeout(this._timeout) clearTimeout(this._connTimer)
}
if (this._reconTimer) {
clearTimeout(this._reconTimer)
} }
if (!this.connected) { if (!this.connected) {
@ -111,20 +129,33 @@ export class NekoWebSocket extends EventEmitter<NekoWebSocketEvents> {
this._log.info(`connected`) this._log.info(`connected`)
this.emit('connected') this.emit('connected')
// reset reconnect timeout
this._reconnTimeout = reconnTimeout
} }
private onTimeout() { private onTimeout() {
this._log.info(`connection timeout`) this._log.info(`connection timeout`)
this.disconnect(new Error('connection timeout')) this.disconnect(new Error('connection timeout'))
this.tryReconnect()
} }
private onError() { private onError() {
this._log.info(`connection error`) this._log.info(`connection error`)
this.disconnect(new Error('connection error')) this.disconnect(new Error('connection error'))
this.tryReconnect()
} }
private onClose() { private onClose() {
this._log.info(`connection closed`) this._log.info(`connection closed`)
this.disconnect(new Error('connection closed')) this.disconnect(new Error('connection closed'))
this.tryReconnect()
}
private onReconnect() {
this._log.info(`reconnecting after ${this._reconnTimeout}ms`)
this._reconnTimeout *= reconnMultiplier
this.connect()
} }
} }

View File

@ -172,7 +172,7 @@
} }
if (this.connected) { if (this.connected) {
this.websocketDisconnect() this.websocket.disconnect(new Error('logged out'))
} }
try { try {
@ -360,15 +360,6 @@
this.webrtc.disconnect() this.webrtc.disconnect()
this.clearState() this.clearState()
// reconnect Websocket
if (this.authenticated) {
setTimeout(() => {
try {
this.websocket.connect()
} catch (e) {}
}, 1000)
}
}) })
// webrtc // webrtc