diff --git a/client/svelte-client/src/components/NetworkSessionWrapper.svelte b/client/svelte-client/src/components/NetworkSessionWrapper.svelte index 3440d9f..266bc2e 100644 --- a/client/svelte-client/src/components/NetworkSessionWrapper.svelte +++ b/client/svelte-client/src/components/NetworkSessionWrapper.svelte @@ -24,11 +24,8 @@ case SessionType.PEER: networkEvents.produce({inputs: $sessionInputs, session_id: session.session_id, player: session.you.id, ts: Date.now()}) break; - case SessionType.OBSERVER: - networkEvents.produce({session_id: session.session_id, player: session.you.id, ts: Date.now()}) - break; default: - throw new Error("session snapshot update not implemented for session type " + session.type); + // noop } } diff --git a/client/svelte-client/src/store/model/session.ts b/client/svelte-client/src/store/model/session.ts index 856c46a..7b6bc1d 100644 --- a/client/svelte-client/src/store/model/session.ts +++ b/client/svelte-client/src/store/model/session.ts @@ -67,10 +67,22 @@ export type PeerSessionSnapshot = { ts: number } -export type ObserverSessionSnapshot = { +export type SessionSnapshot = HostSessionSnapshot | PeerSessionSnapshot; + +export type Heartbeat = { session_id: string, player: string, ts: number } -export type SessionSnapshot = HostSessionSnapshot | PeerSessionSnapshot | ObserverSessionSnapshot; +export enum MessageType { + Snapshot = "SessionSnapshot", Heartbeat = "HeartBeat" +} + +export type Message = { + msg_type: MessageType.Snapshot, + payload: SessionSnapshot +} | { + msg_type: MessageType.Heartbeat, + payload: Heartbeat +} diff --git a/client/svelte-client/src/store/session.ts b/client/svelte-client/src/store/session.ts index 3b89cf4..177d7ab 100644 --- a/client/svelte-client/src/store/session.ts +++ b/client/svelte-client/src/store/session.ts @@ -2,10 +2,10 @@ import {derived, get, readable, writable} from "svelte/store"; import {keysPressed} from "./io"; import api from "../api/session"; import session from "../api/session"; -import type {LocalSession, NetworkSession, Session, SessionSnapshot} from "./model/session"; -import {isLocalSession, SessionState, SessionType} from "./model/session"; +import type {LocalSession, Message, NetworkSession, Session, SessionSnapshot} from "./model/session"; +import {isLocalSession, MessageType, SessionState, SessionType} from "./model/session"; import type {NetworkStore} from "./network"; -import type {GameEvent, GameEventWrapper, SessionEventPayload} from "./model/event"; +import type {GameEventWrapper, SessionEventPayload} from "./model/event"; const sessionStore = writable(null) @@ -51,9 +51,10 @@ function createNetworkEvents() { const {subscribe, set, update} = writable([]); const websocket = writable(null); - const sessionId = writable(null) + const sessionId = writable(null); + const lastSnapshot = writable(null); - const unsubscribe = sessionStore.subscribe(session => { + const unsubscribeSession = sessionStore.subscribe(session => { if (!session || isLocalSession(session)) { return; } @@ -87,19 +88,32 @@ function createNetworkEvents() { }); }) - function produce(sessionSnapshot: SessionSnapshot) { + const interval = setInterval(() => { + const last = get(lastSnapshot); + if (last === null) { + return; + } + const now = Date.now(); + if (now - last.ts < 1_000) { + return + } + console.debug("sending heartbeat") + sendMessage({msg_type: MessageType.Heartbeat, payload: {session_id: last.session_id, player: last.player, ts: now}}); + }, 1_000) + + function sendMessage(message: Message) { const ws = get(websocket); if (!ws) { return; } - console.debug("producing snapshot to ws: ", sessionSnapshot); - ws.send(JSON.stringify(sessionSnapshot)); + console.debug("producing message to ws: ", message); + ws.send(JSON.stringify(message)); } - // return () => { - // get(websocket).close(); - // unsubscribe(); - // } + function produce(snapshot: SessionSnapshot) { + lastSnapshot.set(snapshot); + sendMessage({msg_type: MessageType.Snapshot, payload: snapshot}); + } // TODO: Handle unsubscribe return {