v0.15.1
This commit is contained in:
@@ -26,7 +26,7 @@ const preferredTheme = ['system', 'light', 'dark'].includes(getCookie('gree_cont
|
||||
|
||||
const app = {
|
||||
devices: [], zones: [], groups: [], deviceGroups: [], deviceGroupEnergy: {}, schedules: [], automations: [], flows: [], accessTokens: [], settings: null, system: {}, outdoorTemperature: null,
|
||||
token: localStorage.getItem('gree_controller_token') || '', authTokenSubmitted: false, ws: null, wsTimer: null,
|
||||
token: localStorage.getItem('gree_controller_token') || '', authTokenSubmitted: false, ws: null, wsTimer: null, wsErrorTimer: null,
|
||||
currentView: 'dashboard', loading: false, bootstrapReloadPending: false, language: preferredLanguage, theme: preferredTheme, connectionStatus: 'connecting',
|
||||
languages: [], translations: {}, locales: {}, defaultLanguage: DEFAULT_LANGUAGE,
|
||||
historyTab: 'overview', historyData: { zones: [], devices: [], sensors: [] }, historyCounts: {},
|
||||
|
||||
@@ -131,17 +131,50 @@ async function handleWebSocketMessage(event) {
|
||||
} catch (_) { }
|
||||
}
|
||||
|
||||
const WS_RECONNECT_DELAY_MS = 3000;
|
||||
const WS_CONNECTION_ERROR_DELAY_MS = 15000;
|
||||
|
||||
function clearWebSocketErrorTimer() {
|
||||
clearTimeout(app.wsErrorTimer);
|
||||
app.wsErrorTimer = null;
|
||||
}
|
||||
|
||||
function startWebSocketErrorTimer() {
|
||||
if (app.wsErrorTimer) return;
|
||||
app.wsErrorTimer = setTimeout(() => {
|
||||
app.wsErrorTimer = null;
|
||||
if (!app.ws || app.ws.readyState !== WebSocket.OPEN) updateConnectionIndicator('connectionError');
|
||||
}, WS_CONNECTION_ERROR_DELAY_MS);
|
||||
}
|
||||
|
||||
function connectWebSocket() {
|
||||
if (app.ws && [WebSocket.OPEN, WebSocket.CONNECTING].includes(app.ws.readyState)) return;
|
||||
clearTimeout(app.wsTimer);
|
||||
app.wsTimer = null;
|
||||
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const query = app.token ? `?token=${encodeURIComponent(app.token)}` : '';
|
||||
const ws = new WebSocket(`${protocol}//${location.host}${withBase('/ws')}${query}`); app.ws = ws;
|
||||
ws.onopen = () => updateConnectionIndicator('connected');
|
||||
ws.onclose = () => { app.controlPlanPushReady = false; updateConnectionIndicator('disconnected'); scheduleControlPlanLoad(0); app.wsTimer = setTimeout(connectWebSocket, 3000); };
|
||||
ws.onerror = () => updateConnectionIndicator('connectionError');
|
||||
const ws = new WebSocket(`${protocol}//${location.host}${withBase('/ws')}${query}`);
|
||||
app.ws = ws;
|
||||
ws.onopen = () => {
|
||||
if (app.ws !== ws) return;
|
||||
clearWebSocketErrorTimer();
|
||||
updateConnectionIndicator('connected');
|
||||
};
|
||||
ws.onclose = () => {
|
||||
if (app.ws !== ws) return;
|
||||
app.ws = null;
|
||||
app.controlPlanPushReady = false;
|
||||
if (app.connectionStatus !== 'connectionError') updateConnectionIndicator('reconnecting');
|
||||
startWebSocketErrorTimer();
|
||||
scheduleControlPlanLoad(0);
|
||||
app.wsTimer = setTimeout(connectWebSocket, WS_RECONNECT_DELAY_MS);
|
||||
};
|
||||
// onclose owns the visible connection state. A transient onerror must not
|
||||
// present an application failure while HTTP fallback and reconnect still work.
|
||||
ws.onerror = () => { };
|
||||
let messageQueue = Promise.resolve();
|
||||
ws.onmessage = event => {
|
||||
if (app.ws !== ws) return;
|
||||
messageQueue = messageQueue.then(() => handleWebSocketMessage(event)).catch(() => { });
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user