【问题标题】:SignalR ApplicationUserManager is disposed while using webSockets transportSignalR ApplicationUserManager 在使用 webSockets 传输时被释放
【发布时间】:2016-03-17 09:15:41
【问题描述】:

我已将 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);

【问题讨论】:

  • 你试过在像 Fiddler 这样的代理中查看它吗?
  • 由于已处置 Identity 对象,服务器上发生此错误。 Fiddler、Postman 等只会看到服务器响应的内容。在这种情况下,Postman 可能会收到 500 服务器错误。该响应将归因于特定的实施。 Fiddler 可能没有帮助。
  • ApplicationUserManager 是范围服务吗?正如您从 Context.Request 中获得的那样,我相信如此。因此,当您尝试获取它已经被处置的对象时。尝试更改此行 CurrentUser = ConnectedUsers.GetOrAdd(this.Context.ConnectionId, UserManager.FindByName(this.Context.User.Identity.Name)); 以实际获取 UserManager 执行而不是使用属性。

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


【解决方案1】:

看起来您使用了身份验证令牌(Bearer 或其他东西)。 SignalR 默认情况下不向服务器发送身份验证令牌。所以,上下文是空的。请参阅 Microsoft 文档 https://docs.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 会将令牌值包含到 Request.Query 参数中作为“access_token”,并且不可能将“access_token”名称更改为另一个名称(例如“token”) .因此,您需要在后端实现一个额外的处理程序或中间件来验证和填充 Context。

context.Request.Query["access_token"]

【讨论】:

    【解决方案2】:

    您可以尝试以下步骤:

    1. 在 Fiddler 中打开流式传输。
    2. 如果您的 SignalR 传输是 WebSockets,则在 Fiddler 开启时,请求可能需要几秒钟才能完成。

    【讨论】:

      【解决方案3】:

      使用 WebSockets SignalR 连接,初始 tcp 连接升级为 ws 连接。 UserManager 上下文在 Hub 连接升级和初始化后被释放。

      我建议使用 OAuth Bearer Token 方法。与其在每个 SignalR 方法中调用 this.Context.User.Identity.Name,不如从承载令牌中获取 UserName。

      Microsoft 文档显示了一个示例: Bearer token authentication

      【讨论】:

        猜你喜欢
        • 2018-09-11
        • 1970-01-01
        • 2019-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多