diff --git a/gui/dashboard/apiclient.js b/gui/dashboard/apiclient.js new file mode 100644 index 0000000..fb75e7c --- /dev/null +++ b/gui/dashboard/apiclient.js @@ -0,0 +1,40 @@ +import { ringBell } from './lib'; + +const socketUrl = window.location.href.replace('http', 'ws') + '/socket'; +let reconnectAttempts = 0; +let ws; + +export async function connect({ onData }) { + ws = new WebSocket(socketUrl); + + ws.onmessage = async evt => { + const data = JSON.parse(evt.data || 'false'); + + switch (data.cmd) { + case 'data': + onData(data); + break; + + case 'bell': + ringBell(); + break; + + default: + break; + } + }; + + ws.onopen = () => { + if (reconnectAttempts) { + window.location.reload(); + } + }; + + ws.onclose = async () => { + console.error(`Websocket closed, trying to reconnect... (#${reconnectAttempts++})`); + await new Promise(res => setTimeout(res, reconnectAttempts * 500)); + await connect({ onData }); + }; + + ws.onerror = err => console.error('Connection error', err); +} diff --git a/gui/dashboard/app.svelte b/gui/dashboard/app.svelte index 1b3117c..bb99db4 100644 --- a/gui/dashboard/app.svelte +++ b/gui/dashboard/app.svelte @@ -3,7 +3,8 @@ import TileRawValue from './tile-rawvalue.svelte'; import Settings from './settings.svelte'; import { flip } from 'svelte/animate'; - import { settings, shuffle, ringBell } from './lib'; + import { settings, shuffle } from './lib'; + import { connect } from './apiclient'; const [ send, receive ] = shuffle; let size = ($settings.cols || 4) * ($settings.rows || 3); @@ -69,29 +70,14 @@ tiles = servicesTemp; } - onMount(() => { - const ws = new WebSocket( - window.location.href.replace('http', 'ws') + '/socket' - ); - - ws.onmessage = async evt => { - const data = JSON.parse(evt.data || '""'); - - switch (data.cmd) { - case 'data': - globalData = data; - organiseGrid(); - hasData = true; - break; - - case 'bell': - ringBell(); - break; - - default: - break; - } - } + onMount(async () => { + await connect({ + onData: data => { + globalData = data; + organiseGrid(); + hasData = true; + }, + }); const clockInterval = setInterval(() => { time = new Date().toLocaleTimeString('en-GB', {