Add proper "helo" message to protocol so client can be sure server is ready to receive input.

This commit is contained in:
Tangent Wantwight 2020-05-17 23:39:28 -04:00
parent 9df57e4aa9
commit 6491588223
2 changed files with 25 additions and 7 deletions

View file

@ -30,6 +30,10 @@ export const enum MessageTypes {
export type Packet<TypeId, Payload> = { t: TypeId } & Payload; export type Packet<TypeId, Payload> = { t: TypeId } & Payload;
export type Meta = {
helo?: string;
};
export type ClientMessage<LocalInput, State> = export type ClientMessage<LocalInput, State> =
| Packet<MessageTypes.SET_STATE, { s: Partial<State> }> | Packet<MessageTypes.SET_STATE, { s: Partial<State> }>
| Packet<MessageTypes.INPUT, { i: LocalInput }> | Packet<MessageTypes.INPUT, { i: LocalInput }>
@ -37,6 +41,7 @@ export type ClientMessage<LocalInput, State> =
; ;
export type ServerMessage<GlobalInput, State> = export type ServerMessage<GlobalInput, State> =
| Packet<MessageTypes.META, Meta>
| Packet<MessageTypes.SET_STATE, { u: number, s: Partial<State> }> | Packet<MessageTypes.SET_STATE, { u: number, s: Partial<State> }>
| Packet<MessageTypes.INPUT, { i: GlobalInput }> | Packet<MessageTypes.INPUT, { i: GlobalInput }>
| Packet<MessageTypes.GET_STATE, { c: number }> | Packet<MessageTypes.GET_STATE, { c: number }>
@ -85,11 +90,6 @@ export abstract class LockstepClient<LocalInput, GlobalInput, State> {
} }
}); });
// talkback should exist at this point, send reset message
if(this.serverTalkback) {
this.serverTalkback(1, {t: MessageTypes.SET_STATE, s: {}});
}
// disposal // disposal
return () => { return () => {
this.serverTalkback?.(2); this.serverTalkback?.(2);
@ -110,6 +110,14 @@ export abstract class LockstepClient<LocalInput, GlobalInput, State> {
private processMessage(message: ServerMessage<GlobalInput, State>) { private processMessage(message: ServerMessage<GlobalInput, State>) {
switch (message.t) { switch (message.t) {
case MessageTypes.META:
if(message.helo) {
console.log(`Connected to ${message.helo}`);
// Connection established, reset state for now
this.serverTalkback?.(1, {t: MessageTypes.SET_STATE, s: {}});
}
break;
case MessageTypes.SET_STATE: case MessageTypes.SET_STATE:
const resetState = this.initState(message.s); const resetState = this.initState(message.s);
this.state = new LockstepState(resetState, this.engine); this.state = new LockstepState(resetState, this.engine);

View file

@ -3,9 +3,19 @@ import pipe from "callbag-pipe";
import share from "callbag-share"; import share from "callbag-share";
import { INPUT_FREQUENCY } from "../ecs/Lockstep"; import { INPUT_FREQUENCY } from "../ecs/Lockstep";
import { catchTalkback, defer, interval, makeSubject, map, merge } from "../utilities/Callbag"; import {
catchTalkback,
defer,
interval,
lazy,
makeSubject,
map,
merge,
} from "../utilities/Callbag";
import { ClientMessage, MessageTypes, ServerMessage } from "./LockstepClient"; import { ClientMessage, MessageTypes, ServerMessage } from "./LockstepClient";
const heloSource: Callbag<never, ServerMessage<never, never>> = lazy(() => ({ t: MessageTypes.META, helo: "In-Process Loopback Server" }));
/** Stub loopback server that handles multiple clients, for schemes where GlobalInput = LocalInput[] */ /** Stub loopback server that handles multiple clients, for schemes where GlobalInput = LocalInput[] */
export class LoopbackServer<LocalInput, State> { export class LoopbackServer<LocalInput, State> {
@ -26,7 +36,7 @@ export class LoopbackServer<LocalInput, State> {
public readonly socket = defer(() => { public readonly socket = defer(() => {
const playerNumber = this.nextClientId++; const playerNumber = this.nextClientId++;
return pipe( return pipe(
this.serverFeed, merge(this.serverFeed, heloSource),
catchTalkback((message: ClientMessage<LocalInput, State>) => this.processMessage(playerNumber, message)), catchTalkback((message: ClientMessage<LocalInput, State>) => this.processMessage(playerNumber, message)),
map(message => this.postprocessResponse(playerNumber, message)) map(message => this.postprocessResponse(playerNumber, message))
); );