【问题标题】:How to get user for every connection?如何为每个连接获取用户?
【发布时间】:2019-07-22 13:59:41
【问题描述】:

我正在使用 JWT 令牌对用户进行身份验证。它工作正常,Context.User 被正确填充。问题是它只有一个用户,集线器不是每个连接都有一个用户吗?

OnNotification 方法中,我想循环浏览所有当前连接,验证用户是否有权查看我要发送的内容,然后如果他/她有权限则发送,否则就发送。

我怎样才能做到这一点?

  [Authorize]
  public class NotifyHub : Hub {
    private readonly MyApi _api;

    public NotifyHub(MyApi api) {
      _api = api;
      _api.Notification += OnNotification;
    }

    private async void OnNotification(object sender, Notification notification) {
      //  can access Context.User here
      await Clients.All.SendAsync("Notification", notification);
    }
  }

【问题讨论】:

  • 解决方法Here 的示例。但你会改用Context.User

标签: c# authentication asp.net-core signalr asp.net-core-signalr


【解决方案1】:

当您使用 Hub 时,您可以在调用方客户端 (Clients.Caller)、一个特定客户端 (Clients.User("client_id"))、一组客户端 (Clients.Group("group name")) 和所有客户端 (Clients.All) 上调用方法)。

如果这些都不符合您的需求,您应该实现自己的类来跟踪连接到Hub 的用户(这很容易,因为集线器有OnConnectedAsyncOnDisconnectedAsync 事件处理程序,我通常会这样做它带有一个单例类和一个列表,以及一些锁,只是为了线程安全)。

请注意,集线器是暂时的。它们在收到客户的请求之前不存在,并在请求完成后立即处理。所以不建议订阅事件。集线器是IDisposable,因此框架将在请求完成后释放它们,因此在事件到达时它们可能已经被释放。您应该将IHubContext<NotifyHub>(将集线器的客户端存储在内存中)注入您的MyApi,并将其与您连接的用户存储类一起使用。

【讨论】:

  • 我的中心被添加为单例services.AddSingleton<NotifyHub, NotifyHub>();
  • 我真的不认为这是一个好主意,至少我没有看到有人这样做 :D。例如,通过将集线器设为单例,您将无法访问其中的任何范围服务,而且我认为集线器使用的资源如果是单例也不会被释放。如果您的集线器是单例,线程安全也可能是一个问题。
  • 但是,如果我的中心每秒创建 100 次用于传出作业进度更新,这不会是性能问题吗?
  • 如果它对性能有很大影响,我认为它不会被设计成那样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 2019-04-04
相关资源
最近更新 更多