c# - 检测用户何时离开(即关闭浏览器)
问题描述
我有一个 Singleton 服务,GameServer
它跟踪访客到特定页面、Game.razor
页面和 Scoped 服务,GameBridge
它们之间。 Gamebridge
被注入Game.razor
,GameServer
被注入Gamebridge
.
GameServer
发出一个 ping 事件,该事件由GameBridge
该页面中继。然后页面调用 中的方法Gamebridge
,该方法被中继到GameServer
,并LastSeen
为用户将 DateTime 设置为 DateTime.Now。
这个想法是,如果用户关闭他们的浏览器,Scoped 服务将被GameServer
释放,并且将不再从用户那里获得更新 ping,即用户已超时,游戏可能会被没收,游戏室被放弃等等。
问题是,即使浏览器已关闭,Game.razor
并且GameBridge
继续运行,一切都很好——我可以看到,因为丢失用户的时间值不断更新。截至目前,即使用户在 blazor 服务器端关闭浏览器,我也无法检测到用户断开连接。
解决方案
我的解决方案与浏览器窗口beforeunload
事件挂钩,并使用 Guid 来跟踪 SPA 会话。
这是我的演示系统,您可以根据自己的代码进行调整。
添加一个单例服务并注册它。
using System;
namespace Blazor.App.Services
{
public class SessionTrackerService
{
// Session List, blah, blah, ..
public void NotifyNewSession(Guid ID)
{
// Do whatever you want
Debug.WriteLine($"Session {ID} Registered");
}
public void NotifySessionClosed(Guid ID)
{
var x = 0;
Debug.WriteLine($"Session {ID} Closed");
// Do re-registering
}
}
}
site.js在基本页面中注册。
window.blazor_setExitEvent = function (dotNetHelper) {
blazor_dotNetHelper = dotNetHelper;
window.addEventListener("beforeunload", blazor_SetSPAClosed);
}
var blazor_dotNetHelper;
window.blazor_SetSPAClosed = function() {
blazor_dotNetHelper.invokeMethodAsync('SPASessionClosed')
blazor_dotNetHelper.dispose();
}
添加一些代码到App.razor
. SessionID
如果您需要在其他地方使用它,请级联。调用window.blazor_setExitEvent
以设置窗口beforeunload
事件并将其传递给App
.
<CascadingValue Name="SessionID" Value="this.ID">
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
.....
</Router>
</CascadingValue>
@code {
[Inject] private IJSRuntime _js { get; set; }
[Inject] private SessionTrackerService sessionTrackerService { get; set; }
public Guid ID { get; set; } = Guid.NewGuid();
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
sessionTrackerService.NotifyNewSession(ID);
var dotNetReference = DotNetObjectReference.Create(this);
await _js.InvokeVoidAsync("window.blazor_setExitEvent", dotNetReference);
}
}
[JSInvokable("SPASessionClosed")]
public void SPASessionClosed()
{
sessionTrackerService.NotifySessionClosed(ID);
}
我在 Edge、Chrome 和 Firefox 上进行了测试。
推荐阅读
- python - Pandas 将最新日期文件夹/CSV 文件加载到数据框中
- pine-script - Is it possible to retrieve the current bar's color?
- pine-script - Plotting Arrow when Price Passes Indicator Line
- excel - Error handling when 'getElementById' can't find object/value
- yarnpkg - 我如何在 Yarn 2 中共享工作区中的公共依赖项?
- python - 在不更改字符的情况下查找包含子字符串的列表中的所有名称
- python - Keras,使用 model.predict 访问带有 spektral GCN 的中间层输出时的行为不一致
- selenium - SendKeys 仅将文本注入输入字段几秒钟,然后文本立即从输入字段中消失
- sql - 访问交叉表多行作为列标题?
- python - How to calculate sum of two event till the condition breaks in Python? I am new to python