Skip to content

Commit

Permalink
[Blazor] Updated Blazor Server reconnect UI (#55723)
Browse files Browse the repository at this point in the history
# Updated Blazor Server reconnect UI

Improves the default Blazor Server reconnect experience according to common customer feedback.

## Description

Makes the following improvements to the Blazor Server reconnect UI:
* Rather than waiting three seconds before attempting reconnection, then waiting an additional default of 20 seconds between successive attempts, the new default settings use a configurable exponential backoff strategy:
  * Retry as quickly as possible for the first 10 attempts
  * Retry every 5 seconds for the next 10 attempts
  * Retry every 30 seconds until reaching the user-configured max retry count
  * **Note**: Customers can configure their own retry interval calculation function to override the default behavior
* When the user navigates back to the disconnected app from another app or browser tab, a reconnect attempt is immediately made
* If the server can be reached, but reconnection fails because server disposed the circuit, a refresh occurs automatically
* The default reconnect UI shows the number of seconds until the next reconnect attempt instead of the number of attempts remaining
* The styling of the default reconnect UI has been modernized

Fixes #55721

## Customer Impact

Customers of apps built using Blazor Server often complain about the reconnection experience, which has motivated Blazor developers to open issues like #32113 suggesting improvements to reduce the amount of time the customer spends looking at the reconnect UI. This PR addresses many of those common concerns by performing reconnection attempts more aggressively. Unless apps have overridden the default reconnection options, they will automatically get thew new reconnect behavior by upgrading to .NET 9. In addition, the default reconnect UI styling has been updated. Styling changes will not affect apps that have overridden the default reconnect UI.

## Regression?

- [ ] Yes
- [X] No

## Risk

- [ ] High
- [ ] Medium
- [X] Low

This change only affects the reconnection experience when using Blazor Server or Server interactivity in a Blazor Web App. We have existing automated tests verifying core reconnect functionality. It's possible that some customers may have been relying on the previous defaults, but they'll still be able to override the new defaults if desired.

## Verification

- [X] Manual (required)
- [X] Automated

## Packaging changes reviewed?

- [ ] Yes
- [ ] No
- [X] N/A
  • Loading branch information
MackinnonBuck authored May 28, 2024
1 parent da02847 commit 2dc300d
Show file tree
Hide file tree
Showing 8 changed files with 381 additions and 159 deletions.
1 change: 1 addition & 0 deletions src/Components/Components.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"src\\Hosting\\Abstractions\\src\\Microsoft.AspNetCore.Hosting.Abstractions.csproj",
"src\\Hosting\\Hosting\\src\\Microsoft.AspNetCore.Hosting.csproj",
"src\\Hosting\\Server.Abstractions\\src\\Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj",
"src\\Hosting\\TestHost\\src\\Microsoft.AspNetCore.TestHost.csproj",
"src\\Html.Abstractions\\src\\Microsoft.AspNetCore.Html.Abstractions.csproj",
"src\\Http\\Authentication.Abstractions\\src\\Microsoft.AspNetCore.Authentication.Abstractions.csproj",
"src\\Http\\Authentication.Core\\src\\Microsoft.AspNetCore.Authentication.Core.csproj",
Expand Down
27 changes: 23 additions & 4 deletions src/Components/Web.JS/src/Platform/Circuits/CircuitStartOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export function resolveOptions(userOptions?: Partial<CircuitStartOptions>): Circ
}

export interface ReconnectionOptions {
maxRetries: number;
retryIntervalMilliseconds: number;
maxRetries?: number;
retryIntervalMilliseconds: number | ((previousAttempts: number, maxRetries?: number) => number | undefined | null);
dialogId: string;
}

Expand All @@ -49,15 +49,34 @@ export interface ReconnectionHandler {
onConnectionUp(): void;
}

function computeDefaultRetryInterval(previousAttempts: number, maxRetries?: number): number | null {
if (maxRetries && previousAttempts >= maxRetries) {
return null;
}

if (previousAttempts < 10) {
// Retry as quickly as possible for the first 10 tries
return 0;
}

if (previousAttempts < 20) {
// Retry every 5 seconds for the next 10 tries
return 5000;
}

// Then retry every 30 seconds indefinitely
return 30000;
}

const defaultOptions: CircuitStartOptions = {
// eslint-disable-next-line @typescript-eslint/no-empty-function
configureSignalR: (_) => { },
logLevel: LogLevel.Warning,
initializers: undefined!,
circuitHandlers: [],
reconnectionOptions: {
maxRetries: 8,
retryIntervalMilliseconds: 20000,
maxRetries: 30,
retryIntervalMilliseconds: computeDefaultRetryInterval,
dialogId: 'components-reconnect-modal',
},
};
Loading

0 comments on commit 2dc300d

Please sign in to comment.