diff --git a/src/web/Jordnaer/Components/App.razor b/src/web/Jordnaer/Components/App.razor index 7c171bd7..43a25136 100644 --- a/src/web/Jordnaer/Components/App.razor +++ b/src/web/Jordnaer/Components/App.razor @@ -69,7 +69,12 @@ @*TODO: Add loading image*@ - + + @*Start and reconnection logic based on: https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/signalr?view=aspnetcore-7.0#automatically-refresh-the-page-when-server-side-reconnection-fails*@ + + + + diff --git a/src/web/Jordnaer/wwwroot/js/boot.js b/src/web/Jordnaer/wwwroot/js/boot.js new file mode 100644 index 00000000..e3cbf6ea --- /dev/null +++ b/src/web/Jordnaer/wwwroot/js/boot.js @@ -0,0 +1,59 @@ +(() => { + const maximumRetryCount = 3; + const retryIntervalMilliseconds = 5000; + const reconnectModal = document.getElementById('reconnect-modal'); + + const startReconnectionProcess = () => { + reconnectModal.style.display = 'block'; + + let isCanceled = false; + + (async () => { + for (let i = 0; i < maximumRetryCount; i++) { + reconnectModal.innerText = `Attempting to reconnect: ${i + 1} of ${maximumRetryCount}`; + + await new Promise(resolve => setTimeout(resolve, retryIntervalMilliseconds)); + + if (isCanceled) { + return; + } + + try { + const result = await Blazor.reconnect(); + if (!result) { + // The server was reached, but the connection was rejected; reload the page. + location.reload(); + return; + } + + // Successfully reconnected to the server. + return; + } catch { + // Didn't reach the server; try again. + } + } + + // Retried too many times; reload the page. + location.reload(); + })(); + + return { + cancel: () => { + isCanceled = true; + reconnectModal.style.display = 'none'; + } + }; + }; + + let currentReconnectionProcess = null; + + Blazor.start({ + reconnectionHandler: { + onConnectionDown: () => currentReconnectionProcess ??= startReconnectionProcess(), + onConnectionUp: () => { + currentReconnectionProcess?.cancel(); + currentReconnectionProcess = null; + } + } + }); +})(); \ No newline at end of file