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