kernel-dns/src/ws.ts

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)
}
}