fix: enhance WebSocket bridge connection to flush pending commands and improve initial sync
This commit is contained in:
@@ -60,9 +60,21 @@ const wsManager = createWebSocketManager(server, {
|
|||||||
apiKey: API_KEY,
|
apiKey: API_KEY,
|
||||||
|
|
||||||
// ---- Bridge lifecycle ----
|
// ---- Bridge lifecycle ----
|
||||||
onBridgeConnect: () => {
|
onBridgeConnect: (ws) => {
|
||||||
console.log('\u{1F309} CC:Tweaked bridge connected via WebSocket');
|
console.log('\u{1F309} CC:Tweaked bridge connected via WebSocket');
|
||||||
wsManager.broadcastToClients({ type: 'state_update', bridgeConnected: true });
|
wsManager.broadcastToClients({ type: 'state_update', bridgeConnected: true });
|
||||||
|
|
||||||
|
// Flush any pending commands queued while no WS bridge was connected.
|
||||||
|
// Replaces the implicit sync that HTTP polling previously provided.
|
||||||
|
const pending = getPendingCommands();
|
||||||
|
if (pending.length > 0) {
|
||||||
|
try {
|
||||||
|
ws.send(JSON.stringify({ type: 'command_batch', commands: pending }));
|
||||||
|
console.log(`[Bridge] Flushed ${pending.length} pending command(s) via WS`);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[Bridge] Failed to flush pending commands:', e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onBridgeMessage: (ws, data) => {
|
onBridgeMessage: (ws, data) => {
|
||||||
@@ -193,6 +205,14 @@ function broadcastToClients(data) {
|
|||||||
wsManager.broadcastToClients(data);
|
wsManager.broadcastToClients(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a filtered copy of pending commands (clears expired entries).
|
||||||
|
// Used by both the HTTP polling endpoint and WS initial sync.
|
||||||
|
function getPendingCommands() {
|
||||||
|
const now = Date.now();
|
||||||
|
pendingCommands = pendingCommands.filter(cmd => (now - cmd.timestamp) < 30000);
|
||||||
|
return [...pendingCommands];
|
||||||
|
}
|
||||||
|
|
||||||
// Pushes a command to the CC:Tweaked bridge.
|
// Pushes a command to the CC:Tweaked bridge.
|
||||||
// Primary: real-time push via WebSocket (wsManager.sendToBridge).
|
// Primary: real-time push via WebSocket (wsManager.sendToBridge).
|
||||||
// Fallback: queues for HTTP polling if no WS bridge is connected.
|
// Fallback: queues for HTTP polling if no WS bridge is connected.
|
||||||
@@ -986,11 +1006,7 @@ app.post('/api/bridge/state', (req, res) => {
|
|||||||
// Bridge polls for pending commands (auth required — contains operational data)
|
// Bridge polls for pending commands (auth required — contains operational data)
|
||||||
app.get('/api/bridge/commands', requireAuth, (req, res) => {
|
app.get('/api/bridge/commands', requireAuth, (req, res) => {
|
||||||
try {
|
try {
|
||||||
const now = Date.now();
|
const commands = getPendingCommands();
|
||||||
// Clear old commands (>30s)
|
|
||||||
pendingCommands = pendingCommands.filter(cmd => (now - cmd.timestamp) < 30000);
|
|
||||||
|
|
||||||
const commands = [...pendingCommands];
|
|
||||||
res.json({ commands });
|
res.json({ commands });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
|
|||||||
Reference in New Issue
Block a user