From 351a47ef30deeb526325e0f0cf93234424613fad Mon Sep 17 00:00:00 2001 From: he1d1 Date: Sun, 3 Jul 2022 12:59:51 +0100 Subject: [PATCH 1/2] Client tries to reconnect when sockets close --- apps/web/src/App.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 72560e3ff..36faa302d 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -3,7 +3,22 @@ import { ClientCommand, ClientQuery, CoreEvent } from '@sd/core'; import SpacedriveInterface from '@sd/interface'; import React, { useEffect } from 'react'; -const websocket = new WebSocket(import.meta.env.VITE_SDSERVER_BASE_URL || 'ws://localhost:8080/ws'); +const timeouts = [1, 2, 5, 10]; + +const startWebsocket = (timeoutIndex = 0) => { + const ws = new WebSocket(import.meta.env.VITE_SDSERVER_BASE_URL || 'ws://localhost:8080/ws'); + + ws.addEventListener('close', (event) => { + setTimeout( + () => startWebsocket(timeoutIndex++), + timeouts[timeoutIndex] ?? timeouts[timeouts.length - 1] + ); + }); + + return ws; +}; + +const websocket = startWebsocket(); const randomId = () => Math.random().toString(36).slice(2); From b4c0cb68c4d206888b34abdfe1cc571ada146b67 Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Sat, 9 Jul 2022 16:12:51 +0800 Subject: [PATCH 2/2] reconnect websocket on web - with jitter & exponential backoff --- apps/web/src/App.tsx | 62 +++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 36faa302d..7a8eab2a4 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -1,35 +1,47 @@ import { BaseTransport } from '@sd/client'; -import { ClientCommand, ClientQuery, CoreEvent } from '@sd/core'; +import { ClientCommand, ClientQuery } from '@sd/core'; import SpacedriveInterface from '@sd/interface'; import React, { useEffect } from 'react'; -const timeouts = [1, 2, 5, 10]; - -const startWebsocket = (timeoutIndex = 0) => { - const ws = new WebSocket(import.meta.env.VITE_SDSERVER_BASE_URL || 'ws://localhost:8080/ws'); - - ws.addEventListener('close', (event) => { - setTimeout( - () => startWebsocket(timeoutIndex++), - timeouts[timeoutIndex] ?? timeouts[timeouts.length - 1] - ); - }); - - return ws; -}; - -const websocket = startWebsocket(); +const timeouts = [1000, 2000, 5000, 10000]; // In milliseconds const randomId = () => Math.random().toString(36).slice(2); // bind state to core via Tauri class Transport extends BaseTransport { + websocket: WebSocket; requestMap = new Map void>(); constructor() { super(); + this.websocket = new WebSocket( + import.meta.env.VITE_SDSERVER_BASE_URL || 'ws://localhost:8080/ws' + ); + this.attachEventListeners(); + } - websocket.addEventListener('message', (event) => { + async reconnect(timeoutIndex = 0) { + let timeout = + (timeouts[timeoutIndex] ?? timeouts[timeouts.length - 1]) + + (Math.floor(Math.random() * 5000 /* 5 Seconds */) + 1); + + setTimeout(() => { + let ws = new WebSocket(import.meta.env.VITE_SDSERVER_BASE_URL || 'ws://localhost:8080/ws'); + new Promise(function (resolve, reject) { + ws.addEventListener('open', () => resolve(null)); + ws.addEventListener('close', reject); + }) + .then(() => { + this.websocket = ws; + this.attachEventListeners(); + console.log('Reconnected!'); + }) + .catch((err) => this.reconnect(timeoutIndex++)); + }, timeout); + } + + attachEventListeners() { + this.websocket.addEventListener('message', (event) => { if (!event.data) return; const { id, payload } = JSON.parse(event.data); @@ -44,7 +56,13 @@ class Transport extends BaseTransport { } } }); + + this.websocket.addEventListener('close', () => { + console.log('GONE'); + this.reconnect(); + }); } + async query(query: ClientQuery) { const id = randomId(); let resolve: (data: any) => void; @@ -56,7 +74,7 @@ class Transport extends BaseTransport { // @ts-ignore this.requestMap.set(id, resolve); - websocket.send(JSON.stringify({ id, payload: { type: 'query', data: query } })); + this.websocket.send(JSON.stringify({ id, payload: { type: 'query', data: query } })); return await promise; } @@ -71,12 +89,14 @@ class Transport extends BaseTransport { // @ts-ignore this.requestMap.set(id, resolve); - websocket.send(JSON.stringify({ id, payload: { type: 'command', data: command } })); + this.websocket.send(JSON.stringify({ id, payload: { type: 'command', data: command } })); return await promise; } } +const transport = new Transport(); + function App() { useEffect(() => { window.parent.postMessage('spacedrive-hello', '*'); @@ -87,7 +107,7 @@ function App() { {/*
*/}