From 6ec19b618c8b300e420416e4d1b79b5e2b2b13b7 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Tue, 22 Jul 2025 11:00:03 +0800 Subject: [PATCH] WIP: pingpong with logging. --- abstract-relay.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/abstract-relay.ts b/abstract-relay.ts index 995dd79..4f7923f 100644 --- a/abstract-relay.ts +++ b/abstract-relay.ts @@ -7,6 +7,11 @@ import { Queue, normalizeURL } from './utils.ts' import { makeAuthEvent } from './nip42.ts' import { yieldThread } from './helpers.ts' +type RelayWebSocket = WebSocket & { + ping?(): void + on?(event: 'pong', listener: () => void): any +} + export type AbstractRelayConstructorOptions = { verifyEvent: Nostr['verifyEvent'] websocketImplementation?: typeof WebSocket @@ -35,7 +40,7 @@ export class AbstractRelay { private connectionPromise: Promise | undefined private openCountRequests = new Map() private openEventPublishes = new Map() - private ws: WebSocket | undefined + private ws: RelayWebSocket | undefined private incomingMessageQueue = new Queue() private queueRunning = false private challenge: string | undefined @@ -141,24 +146,31 @@ export class AbstractRelay { private async receivePong() { return new Promise((res, err) => { - this.ws?.on('pong', () => res(true)) || err("ws can't listen for pong") + (this.ws && this.ws.on && this.ws.on('pong', () => res(true))) || err("ws can't listen for pong") }) } private async pingpong() { + console.error('pingpong') // if the websocket is connected if (this.ws?.readyState == 1) { + console.error('pingpong readyState==1') // send a ping - this.ws.ping() + console.error('pingpong ping()'); + (this.ws && this.ws.ping) && this.ws.ping() // wait for either a pong or a timeout + console.error('pingpong wait for pong or timeout') const result = await Promise.any([ this.receivePong(), new Promise(res => setTimeout(() => res(false), 10000)) // TODO: opts.pingTimeout ]) + console.error('pingpong result', result) if (result) { + console.error('pingpong scheduling pingpong') // schedule another pingpong setTimeout(() => this.pingpong(), 10000) // TODO: opts.pingFrequency } else { + console.error('pingpong closing socket') this.ws && this.ws.close() } }