mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 19:06:34 +00:00
feat(ws): offline message queue per kiosk (100 cap, drain on reconnect)
This commit is contained in:
parent
a414f98c56
commit
53739ada20
1 changed files with 27 additions and 2 deletions
|
|
@ -119,13 +119,37 @@ function parseCookieValue(header: string, name: string): string | null {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Per-kiosk message queue: if kiosk is offline, buffer messages here.
|
||||||
|
// Drain on reconnect. FIFO, cap at 100 messages per kiosk.
|
||||||
|
const MESSAGE_QUEUE_CAP = 100;
|
||||||
|
const offlineQueues = new Map<number, string[]>();
|
||||||
|
|
||||||
function sendToKiosk(kioskId: number, message: object): boolean {
|
function sendToKiosk(kioskId: number, message: object): boolean {
|
||||||
const k = connectedKiosks.get(kioskId);
|
const k = connectedKiosks.get(kioskId);
|
||||||
if (!k || k.ws.readyState !== WebSocket.OPEN) return false;
|
const payload = JSON.stringify(message);
|
||||||
k.ws.send(JSON.stringify(message));
|
if (!k || k.ws.readyState !== WebSocket.OPEN) {
|
||||||
|
// Queue for later delivery.
|
||||||
|
let q = offlineQueues.get(kioskId);
|
||||||
|
if (!q) { q = []; offlineQueues.set(kioskId, q); }
|
||||||
|
q.push(payload);
|
||||||
|
if (q.length > MESSAGE_QUEUE_CAP) q.shift(); // FIFO eviction
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
k.ws.send(payload);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function drainOfflineQueue(kioskId: number): void {
|
||||||
|
const q = offlineQueues.get(kioskId);
|
||||||
|
if (!q || q.length === 0) return;
|
||||||
|
const k = connectedKiosks.get(kioskId);
|
||||||
|
if (!k || k.ws.readyState !== WebSocket.OPEN) return;
|
||||||
|
for (const msg of q) {
|
||||||
|
try { k.ws.send(msg); } catch { break; }
|
||||||
|
}
|
||||||
|
offlineQueues.delete(kioskId);
|
||||||
|
}
|
||||||
|
|
||||||
function requestKiosk<T = unknown>(kioskId: number, message: object, timeoutMs = 10000): Promise<T> {
|
function requestKiosk<T = unknown>(kioskId: number, message: object, timeoutMs = 10000): Promise<T> {
|
||||||
const requestId = randomUUID();
|
const requestId = randomUUID();
|
||||||
return new Promise<T>((resolve, reject) => {
|
return new Promise<T>((resolve, reject) => {
|
||||||
|
|
@ -303,6 +327,7 @@ export class Plugin extends BSBService<InstanceType<typeof Config>, typeof Event
|
||||||
connectedKiosks.set(kiosk.id, { id: kiosk.id, name: kioskData.name, ws });
|
connectedKiosks.set(kiosk.id, { id: kiosk.id, name: kioskData.name, ws });
|
||||||
obs.log.info("kiosk connected: {name}", { name: kioskData.name });
|
obs.log.info("kiosk connected: {name}", { name: kioskData.name });
|
||||||
ws.send(JSON.stringify({ type: "connected", kiosk_id: kiosk.id }));
|
ws.send(JSON.stringify({ type: "connected", kiosk_id: kiosk.id }));
|
||||||
|
drainOfflineQueue(kiosk.id);
|
||||||
nodered.forward("kiosk.changed", {
|
nodered.forward("kiosk.changed", {
|
||||||
kiosk_id: kiosk.id,
|
kiosk_id: kiosk.id,
|
||||||
kiosk_name: kioskData.name,
|
kiosk_name: kioskData.name,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue