c# - SignalR ApplicationUserManager 在使用 webSockets 传输时被释放

标签 c# asp.net-mvc websocket signalr asp.net-identity

我已将 SignalR 添加到我现有的 MVC 项目中,并尝试使用来自 MVC 的相同 ApplicationUserManager 将用户加载到中心上下文中。

连接完成后,我像这样调用一些服务器方法:

        var alertsHub = $.connection.monitoringHub;

        $(function() {
            alertsHub.client.processAlertChange = function (name, alert) {
                console.log(alert);
            };

            //start the connection
            $.connection.hub.start().done(function () {
                console.log("Connected, transport = " + $.connection.hub.transport.name);
                alertsHub.server.subscribeToMonitor();
            });
        });

在我的 Hub 方法中有一个调用

CurrentUser = ConnectedUsers.GetOrAdd(this.Context.ConnectionId, UserManager.FindByName(this.Context.User.Identity.Name));

UserManager 就是这样的属性

        protected static ConcurrentDictionary<string, ApplicationUser> ConnectedUsers = new ConcurrentDictionary<string, ApplicationUser>();

    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager
    {
        get
        {
            if (_userManager == null)
            {
                _userManager = Context.Request.GetHttpContext().GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
            return _userManager;
        }
    }
    protected ApplicationUser CurrentUser { get; set; }

问题是,当使用 webSockets 传输时,我收到错误“无法访问已处理的对象”

SignalR: webSockets transport connected. Initiating start request.
SignalR: The start request succeeded. Transitioning to the connected state.
SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332, keep alive timeout of 20000 and disconnecting timeout of 300000
Connected to monitoringHub, transport = webSockets
SignalR: Invoking monitoringhub.SubscribeToMonitor
SignalR: monitoringhub.SubscribeToMonitor failed to execute. Error: Cannot access a disposed object.
Object name: 'ApplicationUserManager'.

但是!当我强制 serverSentEvents 传输时 - 没有错误,一切都很好。为什么?以及如何修复...

我的 Startup.cs

            ConfigureAuth(app);

        // Any connection or hub wire up and configuration should go here
        var hubConfiguration = new HubConfiguration();
        hubConfiguration.EnableDetailedErrors = true;

        app.MapSignalR("/sr", hubConfiguration);

        GlobalHost.HubPipeline.RequireAuthentication();
        GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(120);
        GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(300);
        GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(10);

最佳答案

看起来您使用的是身份验证 token (Bearer 或其他)。默认情况下,SignalR 不会向服务器发送身份验证 token 。所以,上下文是空的。请参阅 Microsoft 文档 https://learn.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-5.0

    // Connect, using the token we got.
this.connection = new signalR.HubConnectionBuilder()
    .withUrl("/hubs/chat", { accessTokenFactory: () => this.loginToken })
    .build();

添加 accessTokenFactory(在客户端)后,SignalR 会将 token 值作为“access_token”包含到 Request.Query 参数中,并且无法将“access_token”名称更改为另一个名称(例如“token”) .因此,您需要实现额外的处理程序或中间件来在后端验证和填充上下文。

context.Request.Query["access_token"]

关于c# - SignalR ApplicationUserManager 在使用 webSockets 传输时被释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36056109/

相关文章:

c# - 我如何让 resharper 为我构建一个基于当前字段或类中 Prop 的简单流畅的界面

c# - 在 ASP.Net MVC View 中显示模型列表

c# - Put 方法不可用(或在帮助中可见)

websocket - Nest js websocket 连接不适用于 Angular 11

http - 净/http : concurrency and message passing between coroutines

c# - 使用 HttpResponse 在 C# 中下载具有非英文字符的文件

c# - 创建具有频率的汽车声音

python - HTTP 回调 URL 与 WebSocket 的异步响应?

c# - 在不使用 Round 或 Truncate 的情况下舍入 Double

javascript - 从 JavaScript 访问 ViewBag