【问题标题】:How to detect that a client closed the browser on Blazor server side (web socket connection closed)?如何检测客户端关闭了 Blazor 服务器端的浏览器(Web 套接字连接关闭)?
【发布时间】:2020-01-31 15:13:58
【问题描述】:

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

【问题讨论】:

    标签: blazor blazor-server-side


    【解决方案1】:

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

    检测用户何时离开组件或组件何时被丢弃,但无法辨别这是由于单击应用程序中的链接还是仅仅因为导航到不同的 URL 或关闭浏览器窗口:

    AddressBase.razor.cs:

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

    地址.razor:

    @page "/address"
    @inherits AddressBase
    
    <h1>Address component</h1>
    

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

    检测用户是否真正离开了应用程序:

    Blazor 使用 Blazor 电路来维护有关用户和范围服务的信息。电路具有生命周期事件,并且可以为它们注册事件处理程序。为此,请扩展 CircuitHandler 类并使用 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

    【讨论】:

    • 这仅检测用户何时离开页面。链接单击(更改页面)或断开连接(关闭选项卡)之间没有区别。
    • 确实 - IDisposable 仅检测用户离开页面(或应用程序)。如果我们在作用域服务上使用 IDisposed,则可以检测到用户已离开应用程序。我会更新解决方案。
    • 谢谢!我认为值得注意的是,OnConnectionUpAsync 将在初始连接后执行一次(在OnCircuitOpenedAsync 执行后),然后在每次重新连接时再次执行。
    猜你喜欢
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 2014-08-11
    相关资源
    最近更新 更多