Blazor server is a fantastic technology, but it constantly breaks with SignalR not being able to reconnect to the server.
How would one fix this in production? I'm having people leaving their laptops in sleep or putting phone with website for a 5 seconds away, than - "Attempting to reconnect".
And always failed. Users are waiting just to see "Reload" button.
Hot to overcome this issue and force reconnect SignalR, even if website was not active in mobile browsers or browsers of sleeping pc?
Blazor has built in options for customising the startup process, but they are not really documented very well.
This is it as far as I can tell: Configure the SignalR client for Blazor Server apps
However there are more options, including the ability to set re-connection options.
In the code sample below, I am setting maxRetries and retryIntervalMilliseconds (lines 48/49) - which define how aggressively the client will try to reconnect in the event of a communication breakdown.
I also configure a custom reconnectionHandler (line 51) with a minimal implementation that will attempt to reconnect (without showing any UI) and if all attempts fail, it will simply reload the page.
This is not a particularly clever thing to do, but it works as a sample to demonstrate how you might go about customising the process.
Further Reading AspNetCore Circuits Client Side Code
** PLEASE DO NOT USE THIS SAMPLE IN PRODUCTION - IT IS ILLUSTRATIVE ONLY **
First, turn off the Blazor boot process withautostart="false"
<script autostart="false" src="_framework/blazor.server.js"></script>
Then, you can provide your own connection handler and settings
<script>
async function connectionDown(options) {
console.log("Connection Down - you could do some UI here...");
for (let i = 0; i < options.maxRetries; i++) {
console.log("Waiting for reconnect attempt #"+(i+1)+" ...");
await this.delay(options.retryIntervalMilliseconds);
if (this.isDisposed) {
break;
}
try {
// reconnectCallback will asynchronously return:
// - true to mean success
// - false to mean we reached the server, but it rejected the connection (e.g., unknown circuit ID)
// - exception to mean we didn't reach the server (this can be sync or async)
console.log("Starting Reconnect attempt #"+(i+1)+" ...");
const result = await window.Blazor.reconnect();
if (!result) {
// If the server responded and refused to reconnect, log it
console.error("Server Rejected");
} else {
// Reconnected!
return;
}
} catch (err) {
// We got an exception so will try again
console.error(err);
}
}
// all attempts failed - let's try a full reload
// This could be a UI change instead or something more complicated
location.reload();
}
function delay(durationMilliseconds) {
return new Promise(resolve => setTimeout(resolve, durationMilliseconds));
}
function connectionUp(e) {
// Reconnected
console.log("Connection UP!");
// if you have a UI to hide/change you can do that here.
}
window.Blazor.start({
reconnectionOptions: {
maxRetries: 30,
retryIntervalMilliseconds: 500,
},
reconnectionHandler: {
onConnectionDown: e => connectionDown(e),
onConnectionUp: e => connectionUp(e)
}
});
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With