Fix OBS display and Start button not working
Three issues fixed:
1. Port mismatch: The sidecar reported the OBS port (8080) in the
ready event but the frontend needs the API port (8081). Now reports
the API port so WebSocket/REST connects to the right place.
2. Broadcast from wrong thread: Engine init fires state_changed from
a background thread, but _broadcast_control used get_event_loop()
which returns the wrong loop. Now captures the uvicorn event loop
at startup via on_event("startup").
3. Missed ready state: If the engine finishes before the WebSocket
client connects, the "ready" state_changed was never received.
Added status polling (GET /api/status) on WebSocket connect that
retries every 2s while appState is "initializing".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -54,6 +54,35 @@ async function apiFetch(path: string, options?: RequestInit): Promise<Response>
|
||||
return fetch(url, { ...options, headers });
|
||||
}
|
||||
|
||||
// ── Status polling ──────────────────────────────────────────────────
|
||||
|
||||
let statusPollTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
async function pollStatus() {
|
||||
try {
|
||||
const resp = await fetch(apiUrl("/api/status"));
|
||||
if (resp.ok) {
|
||||
const data = await resp.json();
|
||||
if (data.state) {
|
||||
state.appState = data.state as AppState;
|
||||
}
|
||||
if (data.engine_device) {
|
||||
state.deviceInfo = data.engine_device;
|
||||
}
|
||||
if (data.version) {
|
||||
state.version = data.version;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// API not ready yet, will retry
|
||||
}
|
||||
|
||||
// Keep polling every 2s while still initializing
|
||||
if (state.appState === "initializing" && state.connectionState === "connected") {
|
||||
statusPollTimer = setTimeout(pollStatus, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// ── WebSocket management ─────────────────────────────────────────────
|
||||
|
||||
function connectWebSocket() {
|
||||
@@ -80,6 +109,9 @@ function _openSocket() {
|
||||
clearTimeout(reconnectTimer);
|
||||
reconnectTimer = null;
|
||||
}
|
||||
// Poll status to catch engine ready state that may have been
|
||||
// missed (engine can finish before WebSocket connects)
|
||||
pollStatus();
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
@@ -132,6 +164,10 @@ function _scheduleReconnect() {
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
if (statusPollTimer) {
|
||||
clearTimeout(statusPollTimer);
|
||||
statusPollTimer = null;
|
||||
}
|
||||
if (reconnectTimer) {
|
||||
clearTimeout(reconnectTimer);
|
||||
reconnectTimer = null;
|
||||
|
||||
Reference in New Issue
Block a user