简体   繁体   English

在浏览器关闭时结束 session 抛出异常

[英]Ending session on browser close throws Exception

I am working on an Asp.net zero project with frontend in angular and backend in Asp.net core with database in MS SQL Server.我正在开发一个 Asp.net 零项目,前端在 angular,后端在 Asp.net,核心在 MS SQL 服务器。 I was working on a functionality by which I can call logout function on closing browser or tab to end the session.我正在开发一项功能,通过该功能我可以在关闭浏览器或选项卡时调用注销 function 以结束 session。

Here is the Javascript Code to call logout on browser/tab close :这是Javascript浏览器/选项卡关闭时调用注销的代码:

window.addEventListener("unload", function (e) 
{
    if (context.validNavigation == 0) 
    {
      context._authService.logout();
    }
});

Below is the C# function which works fine if we manually logout via menu click, but fails when we close browser:下面是C# function 如果我们通过菜单单击手动注销,它工作正常,但当我们关闭浏览器时失败:

public async Task LogOut()
        {
            if (AbpSession.UserId != null)
            {
                if (AbpSession.TenantId != null)
                {
                    var user = _userManager.GetUserById((long)AbpSession.UserId);
                    if (user != null)
                    {
                        user.AdminLoginTime = null;
                        _userManager.UpdateAsync(user); **//This is where I get Task exception**
                    }
                    LoginInput loginInput = new LoginInput
                    {
                        EventId = (int)AbpSession.TenantId,
                        Count = _commonLookupAppService.CurrentloginCount().Result
                    };    
                    this._loginHub.Clients.Group("login_" + AbpSession.TenantId).SendAsync("ReceiveLoginStatus", loginInput);
                }
                var tokenValidityKeyInClaims = User.Claims.First(c => c.Type == AppConsts.TokenValidityKey);
                RemoveTokenAsync(tokenValidityKeyInClaims.Value);    
                var refreshTokenValidityKeyInClaims = User.Claims.FirstOrDefault(c => c.Type == AppConsts.RefreshTokenValidityKey);
                if (refreshTokenValidityKeyInClaims != null)
                {                        RemoveTokenAsync(refreshTokenValidityKeyInClaims.Value);
                }    
                if (AllowOneConcurrentLoginPerUser())
                {
                    _securityStampHandler.RemoveSecurityStampCacheItem(
                       AbpSession.TenantId,
                       AbpSession.GetUserId()
                   );
                }
            }
        }

The Task Exception is generated at _userManager.UpdateAsync(user) only when we close browser.只有当我们关闭浏览器时,任务异常才会在 _userManager.UpdateAsync(user) 处生成。 If I do proper logout through menu button click, it works fine.如果我通过单击菜单按钮正确注销,它工作正常。 The Task exception doesnt let record get updated in AbpUsers & SignalR Hub, also the exception exits the c# function. I am not able to resolve this issue on closing browser.任务异常不会让记录在 AbpUsers & SignalR Hub 中更新,异常也会退出 c# function。我无法在关闭浏览器时解决此问题。

Stack Trace:堆栈跟踪:

at Abp.Domain.Uow.UnitOfWorkInterceptor.<InternalInterceptAsynchronous>d__5`1.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at ryt.Web.Controllers.TokenAuthController.<LogOut>d__37.MoveNext() in D:\Ravi_2021\sinyunpl\aspnet-core\src\ryt.Web.Core\Controllers\TokenAuthController.cs:line 343

在此处输入图像描述

In case any of you have faced this issue and found a solution, please let me know.如果你们中的任何人遇到过这个问题并找到了解决方案,请告诉我。

According to Microsoft documentation found here :根据此处找到的 Microsoft 文档:

When the user closes a browser window or tab, or navigates to a new page or refreshes the page, the SignalR connection immediately ends because SignalR client code handles that browser event for you and calls the Stop method.当用户关闭浏览器 window 或选项卡,或者导航到新页面或刷新页面时,SignalR 连接会立即结束,因为 SignalR 客户端代码会为您处理该浏览器事件并调用 Stop 方法。

Perhaps the signalR client is automatically stopping the connection before you are finished working in the Logout method?也许 signalR 客户端在您完成注销方法之前自动停止连接? It would then make sense why the error only happens when you close the tab.这样就可以理解为什么仅在您关闭选项卡时才会发生错误。

When the browser is closed, the TCP connection is closed and the HTTP request is aborted.当浏览器关闭时,TCP连接关闭,HTTP请求中止。

ABP uses the HttpContext.RequestAborted CancellationToken via HttpContextCancellationTokenProvider . ABP 通过HttpContextCancellationTokenProvider使用HttpContext.RequestAborted CancellationToken

To override that behaviour in this case, call CancellationTokenProvider.Use(CancellationToken.None) in a using statement and await your async method calls:要在这种情况下覆盖该行为,请在using语句中调用CancellationTokenProvider.Use(CancellationToken.None)await您的异步方法调用:

public async Task LogOut()
{
    using (CancellationTokenProvider.Use(CancellationToken.None))
    {
        var user = _userManager.GetUserById((long)AbpSession.UserId);
        await _userManager.UpdateAsync(user);
    }
}

Reference: https://github.com/as.netboilerplate/as.netboilerplate/.../CancellationToken_Tests.cs#L56参考: https://github.com/as.netboilerplate/as.netboilerplate/.../CancellationToken_Tests.cs#L56

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM