WIP: hack in pingpong #495

TypeScript does not like the duck typing of .on and .ping (only valid on Node ws).
This commit is contained in:
Chris McCormick 2025-07-20 14:50:14 +08:00 committed by fiatjaf_
parent de1cf0ed60
commit b3cc9f50e5
1 changed files with 31 additions and 0 deletions

View File

@ -49,6 +49,9 @@ export class AbstractRelay {
this.url = normalizeURL(url)
this.verifyEvent = opts.verifyEvent
this._WebSocket = opts.websocketImplementation || WebSocket
// this.pingHeartBeat = opts.pingHeartBeat
// this.pingFrequency = opts.pingFrequency
// this.pingTimeout = opts.pingTimeout
}
static async connect(url: string, opts: AbstractRelayConstructorOptions): Promise<AbstractRelay> {
@ -102,6 +105,9 @@ export class AbstractRelay {
this.ws.onopen = () => {
clearTimeout(this.connectionTimeoutHandle)
this._connected = true
if (this.ws && this.ws.ping) { // && this.pingHeartBeat
this.pingpong()
}
resolve()
}
@ -133,6 +139,31 @@ export class AbstractRelay {
return this.connectionPromise
}
private async receivePong() {
return new Promise((res, err) => {
this.ws?.on('pong', () => res(true)) || err("ws can't listen for pong")
})
}
private async pingpong() {
// if the websocket is connected
if (this.ws?.readyState == 1) {
// send a ping
this.ws.ping()
// wait for either a pong or a timeout
const result = await Promise.any([
this.receivePong(),
new Promise(res => setTimeout(() => res(false), 10000)) // TODO: opts.pingTimeout
])
if (result) {
// schedule another pingpong
setTimeout(() => this.pingpong(), 10000) // TODO: opts.pingFrequency
} else {
this.ws && this.ws.close()
}
}
}
private async runQueue() {
this.queueRunning = true
while (true) {