MWSE/sdk/WSTSProtocol.js

72 lines
2.6 KiB
JavaScript

// WSTS protocol layer — sits between the raw WebSocket and the event pool.
// Routes incoming frames to either a correlated reply handler (numeric id) or
// a named signal handler (string id). Outbound frames are encoded by the codec.
import { WSTSCodec } from './codec.js';
export default class WSTSProtocol {
constructor(mwse) {
this.mwse = mwse;
this.codec = new WSTSCodec();
this._listen();
}
_listen() {
this.mwse.server.onRecaivePack(raw => this.PackAnalyze(raw));
}
// ---- Outbound -------------------------------------------------------
// SendOnly: fire-and-forget WOM frame — no id, no pending waiter.
SendOnly(pack) {
this.mwse.server.tranferToServer(this.codec.encode([pack, 'R']));
}
// SendRequest: request expecting exactly one reply (action 'R' → server replies 'E').
SendRequest(pack, id) {
this.mwse.server.tranferToServer(this.codec.encode([pack, id, 'R']));
}
// StartStream: request expecting multiple replies (server replies 'C' until done).
StartStream(pack, id) {
this.mwse.server.tranferToServer(this.codec.encode([pack, id, 'S']));
}
// SendRaw: bypass codec (used by internal tooling only).
SendRaw(pack) {
this.mwse.server.tranferToServer(JSON.stringify(pack));
}
// ---- Inbound --------------------------------------------------------
// PackAnalyze routes one decoded frame to the right listener.
// raw may be a string (JSON) or an ArrayBuffer (binary, when #42 lands).
PackAnalyze(raw) {
const data = this.codec.decode(raw);
const [payload, id, action] = data;
if (typeof id === 'number') {
// Correlated reply: numeric id maps to a pending request.
const entry = this.mwse.EventPooling.events.get(id);
if (entry) {
entry[0](payload, action);
if (action === 'E') {
// 'E'nd — one-shot request fulfilled; remove the waiter.
this.mwse.EventPooling.events.delete(id);
}
// 'C'ontinue — stream replies stay in the map until the server closes.
} else {
console.warn('MWSE: reply for unknown request id', id);
}
} else {
// Signal: string id (signal name) fans out to all registered listeners.
const listeners = this.mwse.EventPooling.signals.get(id);
if (listeners) {
for (const cb of listeners) cb(payload);
} else {
console.warn('MWSE: unhandled signal', id);
}
}
}
}