Skip to content

Commit 30f8f59

Browse files
authored
Reconnect UI component (#34842)
1 parent 2e06ab2 commit 30f8f59

File tree

2 files changed

+95
-5
lines changed

2 files changed

+95
-5
lines changed

aspnetcore/blazor/fundamentals/signalr.md

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,78 @@ If reconnection fails, the user is instructed to retry or reload the page:
519519

520520
If reconnection succeeds, user state is often lost. Custom code can be added to any component to save and reload user state across connection failures. For more information, see <xref:blazor/state-management>.
521521

522-
:::moniker range=">= aspnetcore-8.0"
522+
:::moniker range=">= aspnetcore-10.0"
523+
524+
To create UI elements that track reconnection state, the following table describes:
525+
526+
* A set of `components-reconnect-*` CSS classes (**Css class** column) that are set or unset by Blazor on an element with an `id` of `components-reconnect-modal`.
527+
* A `components-reconnect-state-changed` event (**Event** column) that indicates a reconnection status change.
528+
529+
| CSS class | Event | Indicates&hellip; |
530+
| --- | --- | --- |
531+
| `components-reconnect-show` | `show` | A lost connection. The client is attempting to reconnect. The reconnection modal is shown. |
532+
| `components-reconnect-hide` | `hide` | An active connection is re-established to the server. The reconnection model is closed. |
533+
| `components-reconnect-retrying` | `retrying` | The client is attempting to reconnect. |
534+
| `components-reconnect-failed` | `failed` | Reconnection failed, probably due to a network failure. |
535+
| `components-reconnect-rejected` | `rejected` | Reconnection rejected. |
536+
537+
When the reconnection state change in `components-reconnect-state-changed` is `failed`, call `Blazor.reconnect()` in JavaScript to attempt reconnection.
538+
539+
When the reconnection state change is `rejected`, the server was reached but refused the connection, and the user's state on the server is lost. To reload the app, call `location.reload()` in JavaScript. This connection state may result when:
540+
541+
* A crash in the server-side circuit occurs.
542+
* The client is disconnected long enough for the server to drop the user's state. Instances of the user's components are disposed.
543+
* The server is restarted, or the app's worker process is recycled.
544+
545+
The developer adds an event listener on the reconnect modal element to monitor and react to reconnection state changes, as seen in the following example:
546+
547+
```javascript
548+
const reconnectModal = document.getElementById("components-reconnect-modal");
549+
reconnectModal.addEventListener("components-reconnect-state-changed",
550+
handleReconnectStateChanged);
551+
552+
function handleReconnectStateChanged(event) {
553+
if (event.detail.state === "show") {
554+
reconnectModal.showModal();
555+
} else if (event.detail.state === "hide") {
556+
reconnectModal.close();
557+
} else if (event.detail.state === "failed") {
558+
Blazor.reconnect();
559+
} else if (event.detail.state === "rejected") {
560+
location.reload();
561+
}
562+
}
563+
```
564+
565+
An element with an `id` of `components-reconnect-max-retries` displays the maximum number of reconnect retries:
566+
567+
```html
568+
<span id="components-reconnect-max-retries"></span>
569+
```
570+
571+
An element with an `id` of `components-reconnect-current-attempt` displays the current reconnect attempt:
572+
573+
```html
574+
<span id="components-reconnect-current-attempt"></span>
575+
```
576+
577+
An element with an `id` of `components-seconds-to-next-attempt` displays the number of seconds to the next reconnection attempt:
578+
579+
```html
580+
<span id="components-seconds-to-next-attempt"></span>
581+
```
582+
583+
The Blazor Web App project template includes a `ReconnectModal` component (`Components/Layout/ReconnectModal.razor`) with collocated stylesheet and JavaScript files (`ReconnectModal.razor.css`, `ReconnectModal.razor.js`) that can be customized as needed. These files can be examined in the ASP.NET Core reference source or by inspecting an app created from the Blazor Web App project template. The component is added to the project when the project is created in Visual Studio with **Interactive render mode** set to **Server** or **Auto** or created with the .NET CLI with the option `--interactivity server` (default) or `--interactivity auto`.
584+
585+
* [`ReconnectModal` component](https://github.com/dotnet/aspnetcore/blob/main/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Layout/ReconnectModal.razor)
586+
* [Stylesheet file](https://github.com/dotnet/aspnetcore/blob/main/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Layout/ReconnectModal.razor.css)
587+
* [JavaScript file](https://github.com/dotnet/aspnetcore/blob/main/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Layout/ReconnectModal.razor.js)
588+
589+
[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
590+
591+
:::moniker-end
592+
593+
:::moniker range=">= aspnetcore-8.0 < aspnetcore-10.0"
523594

524595
To customize the UI, define a single element with an `id` of `components-reconnect-modal` in the `<body>` element content. The following example places the element in the `App` component.
525596

@@ -551,6 +622,8 @@ To customize the UI, define a single element with an `id` of `components-reconne
551622

552623
:::moniker-end
553624

625+
:::moniker range="< aspnetcore-10.0"
626+
554627
```cshtml
555628
<div id="components-reconnect-modal">
556629
Connection lost.<br>Attempting to reconnect...
@@ -562,7 +635,9 @@ To customize the UI, define a single element with an `id` of `components-reconne
562635
563636
Add the following CSS styles to the site's stylesheet.
564637

565-
:::moniker range=">= aspnetcore-8.0"
638+
:::moniker-end
639+
640+
:::moniker range=">= aspnetcore-8.0 < aspnetcore-10.0"
566641

567642
`wwwroot/app.css`:
568643

@@ -574,6 +649,8 @@ Add the following CSS styles to the site's stylesheet.
574649

575650
:::moniker-end
576651

652+
:::moniker range="< aspnetcore-10.0"
653+
577654
```css
578655
#components-reconnect-modal {
579656
display: none;
@@ -604,13 +681,15 @@ The following table describes the CSS classes applied to the `components-reconne
604681
| `components-reconnect-failed` | Reconnection failed, probably due to a network failure. To attempt reconnection, call `window.Blazor.reconnect()` in JavaScript. |
605682
| `components-reconnect-rejected` | Reconnection rejected. The server was reached but refused the connection, and the user's state on the server is lost. To reload the app, call `location.reload()` in JavaScript. This connection state may result when:<ul><li>A crash in the server-side circuit occurs.</li><li>The client is disconnected long enough for the server to drop the user's state. Instances of the user's components are disposed.</li><li>The server is restarted, or the app's worker process is recycled.</li></ul> |
606683

607-
:::moniker range=">= aspnetcore-5.0"
684+
:::moniker-end
685+
686+
:::moniker range=">= aspnetcore-5.0 < aspnetcore-10.0"
608687

609688
Customize the delay before the reconnection UI appears by setting the `transition-delay` property in the site's CSS for the modal element. The following example sets the transition delay from 500 ms (default) to 1,000 ms (1 second).
610689

611690
:::moniker-end
612691

613-
:::moniker range=">= aspnetcore-8.0"
692+
:::moniker range=">= aspnetcore-8.0 < aspnetcore-10.0"
614693

615694
`wwwroot/app.css`:
616695

@@ -622,7 +701,7 @@ Customize the delay before the reconnection UI appears by setting the `transitio
622701

623702
:::moniker-end
624703

625-
:::moniker range=">= aspnetcore-5.0"
704+
:::moniker range=">= aspnetcore-5.0 < aspnetcore-10.0"
626705

627706
```css
628707
#components-reconnect-modal {

aspnetcore/release-notes/aspnetcore-10/includes/blazor.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,15 @@ The [`[Route]` attribute](xref:Microsoft.AspNetCore.Components.RouteAttribute) n
3636
3737
Previously, <xref:Microsoft.AspNetCore.Components.NavigationManager.NavigateTo%2A?displayProperty=nameWithType> scrolled to the top of the page for same-page navigations. This behavior has been changed in .NET 10 so that the browser no longer scrolls to the top of the page when navigating to the same page. This means the viewport is no longer reset when making updates to the address for the current page, such as changing the query string or fragment.
3838
39+
### Reconnection UI component added to the Blazor Web App project template
40+
41+
The Blazor Web App project template now includes a `ReconnectModal` component, including collocated stylesheet and JavaScript files, for improved developer control over the reconnection UI when the client loses the WebSocket connection to the server. The component doesn't insert styles programmatically, so it doesn't violate stricter Content Security Policy (CSP) settings for the `style-src` policy. In prior releases, the default reconnection UI was created by the framework in a way that could cause CSP violations. Note that the default reconnection UI is still used as fallback when the app doesn't define the reconnection UI, such as by using the project template's `ReconnectModal` component or a similar custom component.
42+
43+
New reconnection UI features:
44+
45+
* Apart from indicating the reconnection state by setting a specific CSS class on the reconnection UI element, the new `components-reconnect-state-changed` event is dispatched for reconnection state changes.
46+
* Code can better differentiate the stages of the reconnection process with the new reconnection state "`retrying`," indicated by both the CSS class and the new event.
47+
48+
For more information, see <xref:blazor/fundamentals/signalr?view=aspnetcore-10.0#reflect-the-server-side-connection-state-in-the-ui>.
49+
3950
-->

0 commit comments

Comments
 (0)