From 8dd448db4453a83ca8fbe70d8a735f6012478041 Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Sun, 17 Nov 2024 13:57:34 +0100 Subject: [PATCH] feat: implement naive client ping --- apps/client/src/common/hooks/useSocket.ts | 8 +++++ apps/client/src/common/utils/socket.ts | 20 ++++++++++-- .../panel/network-panel/NetworkInterfaces.tsx | 8 +++-- .../panel/network-panel/NetworkLogPanel.tsx | 32 ++++++++++++++++++- apps/server/src/adapters/WebsocketAdapter.ts | 10 ++++++ apps/server/src/app.ts | 1 + .../src/definitions/runtime/RuntimeStore.ts | 1 + .../definitions/runtime/RuntimeStore.type.ts | 1 + 8 files changed, 74 insertions(+), 7 deletions(-) diff --git a/apps/client/src/common/hooks/useSocket.ts b/apps/client/src/common/hooks/useSocket.ts index 43fb648f0..a990bacc9 100644 --- a/apps/client/src/common/hooks/useSocket.ts +++ b/apps/client/src/common/hooks/useSocket.ts @@ -230,3 +230,11 @@ export const useTimelineStatus = () => { return useRuntimeStore(featureSelector); }; + +export const usePing = () => { + const featureSelector = (state: RuntimeStore) => ({ + ping: state.ping, + }); + + return useRuntimeStore(featureSelector); +}; diff --git a/apps/client/src/common/utils/socket.ts b/apps/client/src/common/utils/socket.ts index aee453a62..4a3446011 100644 --- a/apps/client/src/common/utils/socket.ts +++ b/apps/client/src/common/utils/socket.ts @@ -1,9 +1,17 @@ import { Log, RundownCached, RuntimeStore } from 'ontime-types'; import { isProduction, websocketUrl } from '../../externals'; +import { CLIENT_LIST, CUSTOM_FIELDS, RUNDOWN, RUNTIME } from '../api/constants'; import { invalidateAllCaches } from '../api/utils'; import { ontimeQueryClient } from '../queryClient'; -import { getClientId, getClientName, setClientId, setClientName, setClients } from '../stores/clientStore'; +import { + getClientId, + getClientName, + setClientId, + setClientName, + setClientRedirect, + setClients, +} from '../stores/clientStore'; import { addLog } from '../stores/logger'; import { patchRuntime, runtimeStore } from '../stores/runtime'; @@ -62,6 +70,12 @@ export const connectSocket = () => { } switch (type) { + case 'pong': { + const offset = (new Date().getTime() - new Date(payload).getTime()) * 0.5; + patchRuntime('ping', offset); + updateDevTools({ ping: offset }, ['PING']); + break; + } case 'client-id': { if (typeof payload === 'string') { setClientId(payload); @@ -210,9 +224,9 @@ export const socketSendJson = (type: string, payload?: unknown) => { ); }; -function updateDevTools(newData: Partial) { +function updateDevTools(newData: Partial, store = RUNTIME) { if (!isProduction) { - ontimeQueryClient.setQueryData(RUNTIME, (oldData: RuntimeStore) => ({ + ontimeQueryClient.setQueryData(store, (oldData: RuntimeStore) => ({ ...oldData, ...newData, })); diff --git a/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx b/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx index cf7927fcc..db4c98f98 100644 --- a/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx +++ b/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx @@ -3,7 +3,7 @@ import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp'; import CopyTag from '../../../../common/components/copy-tag/CopyTag'; import useInfo from '../../../../common/hooks-query/useInfo'; import { openLink } from '../../../../common/utils/linkUtils'; -import { serverPort } from '../../../../externals'; +import { isLocalhost, serverPort } from '../../../../externals'; import style from './NetworkInterfaces.module.scss'; @@ -14,9 +14,11 @@ export default function InfoNif() { return (
- {data?.networkInterfaces?.map((nif) => { - const address = `http://${nif.address}:${serverPort}`; + {data.networkInterfaces?.map((nif) => { + // interfaces outside localhost wont have access + if (nif.name === 'localhost' && !isLocalhost) return null; + const address = `http://${nif.address}:${serverPort}`; return ( Network - {isOntimeCloud && Ontime cloud} + {isOntimeCloud && } Ontime is streaming on the following network interfaces @@ -28,3 +32,29 @@ export default function NetworkLogPanel({ location }: PanelBaseProps) { ); } + +function OntimeCloudStats() { + const { ping } = usePing(); + + /** + * Send immediate ping request, and keep sending on an interval + */ + useEffect(() => { + socketSendJson('ping', new Date()); + + const doPing = setInterval(() => { + socketSendJson('ping', new Date()); + }, 5000); + + return () => { + clearInterval(doPing); + }; + }, []); + + return ( + + Ontime cloud + Current ping: {ping}ms + + ); +} diff --git a/apps/server/src/adapters/WebsocketAdapter.ts b/apps/server/src/adapters/WebsocketAdapter.ts index 2dc93a272..ce7efa5cd 100644 --- a/apps/server/src/adapters/WebsocketAdapter.ts +++ b/apps/server/src/adapters/WebsocketAdapter.ts @@ -100,6 +100,16 @@ export class SocketServer implements IAdapter { const message = JSON.parse(data); const { type, payload } = message; + if (type === 'ping') { + ws.send( + JSON.stringify({ + type: 'pong', + payload, + }), + ); + return; + } + if (type === 'get-client-name') { ws.send( JSON.stringify({ diff --git a/apps/server/src/app.ts b/apps/server/src/app.ts index dc1c40ced..d1d47da97 100644 --- a/apps/server/src/app.ts +++ b/apps/server/src/app.ts @@ -188,6 +188,7 @@ export const startServer = async ( direction: SimpleDirection.CountDown, }, frozen: false, + ping: -1, }); // initialise logging service, escalateErrorFn is only exists in electron diff --git a/packages/types/src/definitions/runtime/RuntimeStore.ts b/packages/types/src/definitions/runtime/RuntimeStore.ts index 2634a7125..13dec8b30 100644 --- a/packages/types/src/definitions/runtime/RuntimeStore.ts +++ b/packages/types/src/definitions/runtime/RuntimeStore.ts @@ -52,4 +52,5 @@ export const runtimeStorePlaceholder: RuntimeStore = { playback: SimplePlayback.Stop, }, frozen: false, + ping: -1, }; diff --git a/packages/types/src/definitions/runtime/RuntimeStore.type.ts b/packages/types/src/definitions/runtime/RuntimeStore.type.ts index dfd2c8f9b..074b04c9f 100644 --- a/packages/types/src/definitions/runtime/RuntimeStore.type.ts +++ b/packages/types/src/definitions/runtime/RuntimeStore.type.ts @@ -27,4 +27,5 @@ export type RuntimeStore = { // flags frozen: boolean; + ping: number; };