45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import { Callbag, Source } from "callbag";
|
|
import create from "callbag-create";
|
|
import pipe from "callbag-pipe";
|
|
|
|
import { Jsonified } from "../ecs/Data";
|
|
import { catchTalkback, defer } from "../utilities/Callbag";
|
|
import { ClientMessage, ServerMessage } from "./LockstepClient";
|
|
|
|
type Server<LocalInput, State> = Callbag<ClientMessage<LocalInput, State>, ServerMessage<LocalInput[], State>>;
|
|
|
|
/** Connection to a websocket server that handles multiple clients, for schemes where GlobalInput = LocalInput[] */
|
|
export class Connection<LocalInput, State> {
|
|
|
|
public constructor(
|
|
private url: string
|
|
) { }
|
|
|
|
public readonly socket: Server<LocalInput, State> = defer(() => {
|
|
const ws = new WebSocket(this.url);
|
|
|
|
const source: Source<ServerMessage<LocalInput[], State>> = create((next: (data: ServerMessage<LocalInput[], State>) => void, { }, close) => {
|
|
ws.onmessage = msg => {
|
|
const decoded: Jsonified<ServerMessage<LocalInput[], State>> = JSON.parse(msg.data);
|
|
next(decoded as ServerMessage<LocalInput[], State>);
|
|
};
|
|
ws.onclose = () => {
|
|
close();
|
|
};
|
|
|
|
return () => {
|
|
// cleanup
|
|
ws.close();
|
|
};
|
|
});
|
|
|
|
return pipe(
|
|
source,
|
|
catchTalkback((message: ClientMessage<LocalInput, State>) => {
|
|
const encoded = JSON.stringify(message);
|
|
ws.send(encoded);
|
|
})
|
|
);
|
|
});
|
|
}
|