75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
|
import EventEmitter from "events"
|
||
|
|
||
|
interface Options {
|
||
|
retryCount?: number
|
||
|
reconnectInterval?: number
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Ported from https://github.com/ofirattia/ws-reconnect
|
||
|
*/
|
||
|
export default class WSReconnect extends EventEmitter {
|
||
|
private url: string
|
||
|
private options: Options
|
||
|
private retryCount: number
|
||
|
private _retryCount: number
|
||
|
private reconnectInterval: number
|
||
|
private shouldAttemptReconnect: boolean
|
||
|
private isConnected = false
|
||
|
private socket: WebSocket | undefined
|
||
|
private reconnectTimeoutId: NodeJS.Timeout | undefined
|
||
|
|
||
|
constructor(url: string, options: Options = {}) {
|
||
|
super()
|
||
|
this.url = url
|
||
|
this.options = options
|
||
|
this.retryCount = this.options.retryCount || -1
|
||
|
this._retryCount = this.retryCount
|
||
|
this.reconnectInterval = this.options?.reconnectInterval ?? 5
|
||
|
this.shouldAttemptReconnect = !!this.reconnectInterval
|
||
|
}
|
||
|
|
||
|
start() {
|
||
|
this.shouldAttemptReconnect = !!this.reconnectInterval
|
||
|
this.isConnected = false
|
||
|
this.socket = new WebSocket(this.url)
|
||
|
this.socket.onmessage = this.onMessage.bind(this)
|
||
|
this.socket.onopen = this.onOpen.bind(this)
|
||
|
this.socket.onclose = this.onClose.bind(this)
|
||
|
}
|
||
|
|
||
|
destroy() {
|
||
|
clearTimeout(this.reconnectTimeoutId as NodeJS.Timeout)
|
||
|
this.shouldAttemptReconnect = false
|
||
|
this.socket?.close()
|
||
|
}
|
||
|
|
||
|
onOpen() {
|
||
|
this.isConnected = true
|
||
|
this.emit("connect")
|
||
|
// set again the retry count
|
||
|
this.retryCount = this._retryCount
|
||
|
}
|
||
|
|
||
|
onClose() {
|
||
|
if (this.shouldAttemptReconnect && (this.retryCount > 0 || this.retryCount == -1)) {
|
||
|
if (this.retryCount !== -1) this.retryCount--
|
||
|
clearTimeout(this.reconnectTimeoutId as NodeJS.Timeout)
|
||
|
this.reconnectTimeoutId = setTimeout(() => {
|
||
|
this.emit("reconnect")
|
||
|
this.start()
|
||
|
}, this.reconnectInterval * 1000)
|
||
|
} else {
|
||
|
this.emit("destroyed")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
onMessage(message: MessageEvent) {
|
||
|
this.emit("message", message.data)
|
||
|
}
|
||
|
|
||
|
send(message: string | ArrayBufferLike | Blob | ArrayBufferView) {
|
||
|
this.socket?.send(message)
|
||
|
}
|
||
|
}
|