From 3e89937d2b30eaf9152067e84c72acc0190d385b Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Tue, 18 Oct 2022 16:39:49 -0700 Subject: [PATCH] Handle websocket errors and reconnection. Closes #1869 --- web/components/stores/ClientConfigStore.tsx | 1 + web/services/websocket-service.ts | 42 ++++++++++++++------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/web/components/stores/ClientConfigStore.tsx b/web/components/stores/ClientConfigStore.tsx index cef6e8805..a4cb5572b 100644 --- a/web/components/stores/ClientConfigStore.tsx +++ b/web/components/stores/ClientConfigStore.tsx @@ -68,6 +68,7 @@ export const chatAuthenticatedAtom = atom({ export const websocketServiceAtom = atom({ key: 'websocketServiceAtom', default: null, + dangerouslyAllowMutability: true, }); export const appStateAtom = atom({ diff --git a/web/services/websocket-service.ts b/web/services/websocket-service.ts index 0015c4898..cac5544db 100644 --- a/web/services/websocket-service.ts +++ b/web/services/websocket-service.ts @@ -14,24 +14,24 @@ export default class WebsocketService { websocketReconnectTimer: ReturnType; + isShutdown = false; + + backOff = 1000; + handleMessage?: (message: SocketEvent) => void; constructor(accessToken, path) { this.accessToken = accessToken; this.path = path; - // this.websocketReconnectTimer = null; - // this.accessToken = accessToken; - - // this.websocketConnectedListeners = []; - // this.websocketDisconnectListeners = []; - // this.rawMessageListeners = []; + this.websocketReconnectTimer = null; // this.send = this.send.bind(this); - // this.createAndConnect = this.createAndConnect.bind(this); + this.createAndConnect = this.createAndConnect.bind(this); // this.scheduleReconnect = this.scheduleReconnect.bind(this); - // this.shutdown = this.shutdown.bind(this); + // this.onError = this.onError.bind(this); + this.shutdown = this.shutdown.bind(this); - // this.isShutdown = false; + this.isShutdown = false; this.createAndConnect(); } @@ -46,7 +46,6 @@ export default class WebsocketService { console.debug('connecting to ', url.toString()); const ws = new WebSocket(url.toString()); ws.onopen = this.onOpen.bind(this); - // ws.onclose = this.onClose.bind(this); ws.onerror = this.onError.bind(this); ws.onmessage = this.onMessage.bind(this); @@ -61,12 +60,27 @@ export default class WebsocketService { // On ws error just close the socket and let it re-connect again for now. onError(e) { - console.error(e); handleNetworkingError(`Socket error: ${e}`); this.websocket.close(); - // if (!this.isShutdown) { - // this.scheduleReconnect(); - // } + if (!this.isShutdown) { + this.scheduleReconnect(); + } + } + + scheduleReconnect() { + if (this.websocketReconnectTimer) { + clearTimeout(this.websocketReconnectTimer); + } + this.backOff *= 2; + this.websocketReconnectTimer = setTimeout( + this.createAndConnect, + 5000 + Math.min(this.backOff, 10_000), + ); + } + + shutdown() { + this.isShutdown = true; + this.websocket.close(); } /*