【问题标题】:Is there a way to detect when a user closes the browser in Blazor Server?有没有办法检测用户何时关闭 Blazor Server 中的浏览器?
【发布时间】:2022-11-15 10:28:21
【问题描述】:

我有以下问题:我需要在用户关闭浏览器时运行代码。我希望我的 Blazor Server App 在用户没有按下注销按钮时注销用户。

CircuitHandlerService.cs

  public class CircuitHandlerService : CircuitHandler
    {
        
        public override Task OnCircuitClosedAsync(Circuit circuit, 
    CancellationToken cancellationToken)
        {
            //my code

            return base.OnCircuitClosedAsync(circuit, 
         cancellationToken);
        }
    }

我已经尝试过使用 Dispose()、OnCircuitClosedAsync() 和 OnConnectionDown(),但它们都没有真正运行其中的代码。我确定我做错了什么。

提前致谢!

【问题讨论】:

  • 用户可以在多个浏览器中同时处于活动状态吗?您想如何处理短暂的互联网连接中断(几秒钟)?
  • 我的计划是允许这样做并显示有关连接中断的警告。

标签: c# blazor blazor-server-side


【解决方案1】:

有没有办法检测用户何时关闭 Blazor Server 中的浏览器?

您需要在浏览器 beforeunload 事件上设置侦听器以回调到 Blazor。

首先是一些JS。

// site.js
// load in _Layout_.cshtml
window.blazr_setExitCheck = function (dotNetHelper, set) {
    if (set) {
        window.addEventListener("beforeunload", blazr_spaExit);
        blazrDotNetExitHelper = dotNetHelper;
    }
    else {
        window.removeEventListener("beforeunload", blazr_spaExit);
        blazrDotNetExitHelper = null;
    }
}

var blazrDotNetExitHelper;

window.blazr_spaExit = function (event) {
    event.preventDefault();
    blazrDotNetExitHelper.invokeMethodAsync("SpaExit");
}

站点退出服务。您可以在SpaExit 中运行任何您想要的代码,或者在SPAClosed 中从其他地方注册一个事件处理程序。

public class SiteExitService
{
    private IJSRuntime? _js { get; set; }

    private TaskCompletionSource? _taskCompletionSource;

    public event EventHandler? SPAClosed;

    public SiteExitService(IJSRuntime? js)
        => _js = js;

    public async Task SetSpaExit()
    {
        // makes sure we only do it once
        if (_taskCompletionSource is null)
        {
            _taskCompletionSource = new TaskCompletionSource();
            var objref = DotNetObjectReference.Create(this);
            await _js!.InvokeVoidAsync("blazr_setExitCheck", objref, true);
            _taskCompletionSource.SetResult();
        }

        if (!_taskCompletionSource.Task.IsCompleted)
            await _taskCompletionSource.Task;
    }


    [JSInvokable]
    public Task SpaExit()
    {
        // do whatever you want to do on exit  Raise an event if you wish
        this.SPAClosed?.Invoke(null, EventArgs.Empty);
        return Task.CompletedTask;
    }
}

程序:

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddScoped<SiteExitService>();

在 App 中设置,以便始终加载。

// <Router AppAssembly="@typeof(App).Assembly">
// ...
//</Router>
@code {
    [Inject] private SiteExitService Service { get; set; } = default!;

    protected async override Task OnAfterRenderAsync(bool firstRender)
        => await Service.SetSpaExit();
}

通过在 this.SPAClosed?.Invoke(null, EventArgs.Empty); 上放置断点来检查它是否有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-07
    • 1970-01-01
    • 2021-11-06
    • 2011-08-11
    • 2015-09-11
    • 2021-11-08
    相关资源
    最近更新 更多