From 2d110cffeb9099dc7f80fb87abff5857f4ce9dfa Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Wed, 6 May 2026 16:56:54 -0500 Subject: [PATCH] handle pong event and show round trip latency --- src/app/app.html | 2 +- src/app/services/events.ts | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/app/app.html b/src/app/app.html index 3e1cc73..d3417da 100644 --- a/src/app/app.html +++ b/src/app/app.html @@ -2,7 +2,7 @@
@if (eventsService.status() === 'open') { -
+
} @else if (eventsService.status() === 'closed') {
} @else if (eventsService.status() === 'error') { diff --git a/src/app/services/events.ts b/src/app/services/events.ts index 2018749..b3899ff 100644 --- a/src/app/services/events.ts +++ b/src/app/services/events.ts @@ -13,9 +13,13 @@ export class EventsService { private outputEvents$ = new Subject>(); private settingsService = inject(SettingsService); + private pingInterval?: number; + private lastPingTimestamp?: number; + + public socketRoundTripLatency = signal(null); + constructor() { effect(() => { - console.log('Websocket URL changed:', this.settingsService.wsUrl()); if (this.socket) { this.socket.close(); } @@ -28,6 +32,15 @@ export class EventsService { this.socket = new WebSocket(this.settingsService.wsUrl()); this.socket.onopen = () => { this.status.set('open'); + if (this.pingInterval) { + clearInterval(this.pingInterval); + } + this.pingInterval = setInterval(() => { + if (this.socket && this.socket.readyState === WebSocket.OPEN) { + this.lastPingTimestamp = Date.now(); + this.socket.send(JSON.stringify({ type: 'ping', data: {timestamp: this.lastPingTimestamp} })); + } + }, 5000); }; this.socket.onclose = () => { @@ -54,6 +67,11 @@ export class EventsService { case 'output': this.outputEvents$.next(messageObj); break; + case 'pong': + if (this.lastPingTimestamp) { + this.socketRoundTripLatency.set(Date.now() - this.lastPingTimestamp); + } + break; default: console.warn('Unknown event type:', messageObj.type); }