How can I get the event while page close in blazor server-side?
Asked Answered
R

2

11

I am making a chatroom App by the blazor server-side.

I want to show the online state of each user.

Now I can use the OnAfterRenderAsync event to get a user has entered the page.

It seems there is not any exit event in blazor lifecycle via https://learn.microsoft.com/en-us/aspnet/core/blazor/lifecycle?view=aspnetcore-3.1

Someone said I can use the Dispose event to achieve it while it does work at all.

What's more, I have a crazy idea that using the window.onbeforeunload event of js to invoke the blazor method.

I have no idea which one is best. Would you please give me a suggestion? Thank you.

Ritter answered 30/1, 2020 at 7:19 Comment(6)
"I am making a chatroom App by the blazor server-side" - I would use SignalR instead.Saintebeuve
@VojtěchDohnal Yes, now I am using a SignalR also. I use blazor for I want make a single-page application with C#.Ritter
Isn't entering and leaving the chatroom handled by SignalR then?Saintebeuve
@VojtěchDohnal I tried this. After I closed the page, it doesn't work at all. It seems the connection.Closed event only works while the page is alive.Ritter
It does not handle only the situation when the browser window is closed without logoff otherwise it works well I guess. You mean the SignalR hub OnDisconnectedAsync handler does not work for you?Saintebeuve
@VojtěchDohnal No,I am using this event:learn.microsoft.com/en-us/dotnet/api/…Ritter
S
12

You should implement a CircuitHandler on the server for this.

You can find the documentation here https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.server.circuits.circuithandler?view=aspnetcore-3.1

It enables you to react to lifecycle events for the Circuit, which is the backbone of a Blazor Server connection.

Methods

OnCircuitClosedAsync(Circuit, CancellationToken)
Invoked when a new circuit is being discarded.

OnCircuitOpenedAsync(Circuit, CancellationToken)
Invoked when a new circuit was established.

OnConnectionDownAsync(Circuit, CancellationToken)
Invoked when a connection to the client was dropped.

OnConnectionUpAsync(Circuit, CancellationToken) Invoked when a connection to the client was established. - This method is executed once initially after OnCircuitOpenedAsync(Circuit, CancellationToken) and once each for each reconnect during the lifetime of a circuit.

Sungkiang answered 30/1, 2020 at 8:57 Comment(1)
I found a sample project here also:github.com/nagytam/BlazorCircuitHandler. I tried the sample project and it is just what I need.Ritter
U
0

As Mister Magoo pointed out, Circuit Handler is an effective way to solve this problem.

There is another way, which is based on more custom implementations of the Component base library. You can create an abstract class extending from the component base :

public abstract class CancellableComponentBase : ComponentBase, IDisposable
{
    private CancellationTokenSource? _cancellationTokenSource;
    protected CancellationToken ComponentDetached => (_cancellationTokenSource ??= new()).Token;

    public virtual void Dispose()
    {
        if (_cancellationTokenSource != null)
        {
            _cancellationTokenSource.Cancel();
            _cancellationTokenSource.Dispose();
            _cancellationTokenSource = null;
        }
    }
}

In your _Imports.razor, you have to add:

@inherits CancellableComponentBase

This makes the default inherited class for ALL razor pages cancellable.

This allows you to call the ComponentDetached Cancellation token in your classes. IE:

<h3>Example</h3>
@code {


public void Bar()
{
    Foo(ComponentDetached);
}

private void Foo(CancellationToken cts)
{
    cts.Register(() => Console.WriteLine("page closed"));
}
}

When this page is closed, The delegate calling the console write line will be called.

Edit: Source that helped me out here: https://www.meziantou.net/canceling-background-tasks-when-a-user-navigates-away-from-a-blazor-component.htm

Unready answered 21/9, 2023 at 0:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.