如何检测客户端是否关闭了 Blazor 服务器端的浏览器(网络套接字连接已关闭)?

How to detect that a client closed the browser on Blazor server side (web socket connection closed)?

我正在尝试检测客户端何时与 Blazor 服务器端应用程序断开连接;这可能等于关闭网络套接字连接。你能建议一种在服务器端检测此类事件的方法吗?

我检查了 ASP.NET 核心 3.1 功能并测试了当用户导航离开组件或浏览器关闭时确实可以检测到事件。

检测用户何时离开某个组件或何时丢弃某个组件,但无法辨别这是由于单击应用程序中的 link 还是仅仅因为导航到另一个 URL 或关闭浏览器 window:

AddressBase.razor.cs:

public class AddressBase : ComponentBase, IDisposable
{
        void IDisposable.Dispose()
        {
            Console.WriteLine("Disposing AddressBase.");
        }
}

Address.razor:

@page "/address"
@inherits AddressBase

<h1>Address component</h1>

当浏览器 window 关闭或用户导航到应用程序中的不同视图或完全不同的 URL 时,将为页面上当前显示的所有组件触发 Dispose() 函数。

检测用户是否真的离开了应用:

Blazor 使用 Blazor 电路来维护有关用户和作用域服务的信息。电路有生命周期事件,可以为它们注册事件处理程序。为此,扩展 CircuitHandler class 并使用 DI 注册它。 CircuitHandler 将处理以下事件:

  • OnCircuitOpenedAsync
  • OnConnectionUpAsync
  • OnConnectionDownAsync
  • OnCircuitClosedAsync

它还定义了 Order 属性,可用于多个 CircuitHandler 的执行顺序。

using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Server.Circuits;

public class TrackingCircuitHandler : CircuitHandler
{
    private HashSet<Circuit> circuits = new HashSet<Circuit>();

    public override Task OnConnectionUpAsync(Circuit circuit, 
        CancellationToken cancellationToken)
    {
        circuits.Add(circuit);

        return Task.CompletedTask;
    }

    public override Task OnConnectionDownAsync(Circuit circuit, 
        CancellationToken cancellationToken)
    {
        circuits.Remove(circuit);

        return Task.CompletedTask;
    }

    public int ConnectedCircuits => circuits.Count;
}

// ...

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
}

https://docs.microsoft.com/en-us/aspnet/core/blazor/advanced-scenarios?view=aspnetcore-3.1 https://source.dot.net/#Microsoft.AspNetCore.Components.Server/Circuits/CircuitHandler.cs