Reputation: 47
Currently, if we use an Auto render mode for a component, and the WASM has not previously been downloaded in the browser, the SignalR connection remains open after the WASM download is completed until we either reload the page or navigate to another page with a render mode that does not use SignalR (SSR or WebAssembly). I was wondering if there was some way to change this, i.e., to immediately drop the SignalR connection when the WASM is ready, without the need to reload the current page or navigate to another page?
This is especially important to me because I want to avoid to "Connection lost. Attempting to reconnect" view as much as possible. If SignalR could get dropped immediately after the WASM stuff is downloaded, it would significantly reduce the risks of the Connection lost view appearing.
Thanks!
Upvotes: 2
Views: 96
Reputation: 22029
You can use autostart="false"
to avoid to "Connection lost. Attempting to reconnect" view.
Sample Code like below
<script src="_framework/blazor.web.js" autostart="false"></script>
My attempt
In the Blazor Auto render mode template, when trying to establish a /blazor
connection using either javascript or .net client, you will get the error message: Unable to complete handshake with the server due to an error: The protocol 'json' is not supported .
So I don't think it's a good idea to disconnect the signalr connection through code, because the code encapsulated in Blazor does not expose these options for us to use.
At present, your requirement is not to see the reconnection page, but there is a situation where if the connection with the server is indeed disconnected later, subsequent operations may have problems. Here is a similar alternative solution I have done before for your reference, and you can continue to reconnect.
Here is the sample code for you. You can find the heartbeathub in the link above.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="BlazorApp1.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js" autostart="false"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.0/signalr.min.js"></script>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/heartbeatHub")
.build();
connection.start().then(() => {
console.log("Connected to heartbeatHub");
setInterval(() => {
connection.invoke("SendHeartbeat")
.then(() => console.log("Heartbeat sent"))
.catch(err => console.error(err.toString()));
}, 5 * 60 * 1000);
}).catch(err => console.error(err.toString()));
connection.on("HeartbeatReceived", (message) => {
console.log(`Server response: ${message}`);
});
connection.onclose(async () => {
console.log("Connection closed, retrying...");
try {
await connection.start();
console.log("Reconnected to heartbeatHub");
} catch (err) {
console.error("Reconnect failed: " + err.toString());
}
});
Blazor.start().then(() => {
console.log("Blazor started successfully.");
const reconnectHandler = {
connectionLost: () => {
console.log("Blazor connection lost. Attempting to reconnect...");
setTimeout(() => {
location.reload();
}, 3000);
}
};
Blazor.reconnect = async function () {
console.log("Attempting to reconnect Blazor...");
};
window.addEventListener('unload', reconnectHandler.connectionLost);
}).catch(err => {
console.error("Error while starting Blazor: " + err.toString());
});
</script>
</body>
</html>
Upvotes: 1