【问题标题】:Getting current hub in SignalR在 SignalR 中获取当前集线器
【发布时间】:2022-04-01 17:35:22
【问题描述】:

有没有从控制器调用 SignalR hub 中方法的好方法?

现在我有这个:

public class StatsHub : Hub
{
    private static readonly Lazy<StatsHub> instance = new Lazy<StatsHub>(() => new StatsHub());
    public static StatsHub Instance { get { return instance.Value; } }

    public StatsHub()
    {
        if (this.Clients == null)
        {
            var hubContext = SignalR.GlobalHost.ConnectionManager.GetHubContext<StatsHub>();
            this.Clients = hubContext.Clients;
            this.Groups = hubContext.Groups;
        }
    }

    // methods here...
}

所以在我的控制器操作中我可以说,例如

StatsHub.Instance.SendMessage("blah");

它几乎是好的,除了 hubContext 没有 Hub 的 Caller 或 Context 属性——这些属性很好。

希望有更好的方法吗?

【问题讨论】:

    标签: signalr


    【解决方案1】:

    如果您想从集线器外部通过集线器进行广播,您需要GlobalHost.ConnectionManager.GetHubContext&lt;MyHub&gt;() 来获取集线器上下文。然后,您可以使用此上下文通过 .Clients 属性进行广播。

    如您的示例代码所示,您已经掌握了集线器上下文,但在我看来,在集线器内部这样做感觉不对。如果您仅在控制器操作中使用 SendMessage() 中的逻辑,我会将代码直接移动到控制器操作中并使用通过 GetHubContext&lt;T&gt;() 从那里获得的集线器上下文。

    请注意,CallerContext 属性在这种情况下将始终为 null,因为在向服务器发出请求时不涉及 SignalR,因此无法提供这些属性。

    【讨论】:

      【解决方案2】:

      找到了一个 DefaultHubManager,我想这是我需要的。

      DefaultHubManager hd = new DefaultHubManager(GlobalHost.DependencyResolver);
      var hub = hd.ResolveHub("AdminHub") as AdminHub;
      hub.SendMessage("woohoo");
      

      有效。如果有更好/首选的方法 - 请分享。

      【讨论】:

      • 这不再有效(在 SignalR 2 中?)。见stackoverflow.com/questions/17896739/…
      • DefaultHubManager 存在于 SignalR 2.x 中,但 hub.Context 为空,因此所有操作均失败。
      • 这在 signalR 2.0 中有效,但出现异常 不支持使用不是由 HubPipeline 创建的 Hub 实例
      【解决方案3】:

      根据最新的文档,可以通过依赖注入来注入 IHubContext。

      文档:https://docs.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-6.0

      在服务中你可以做的

      public class NotificationService : INotificationService
      {
          private readonly IHubContext<NotificationHub> _hubContext;
      
          public NotificationService(IHubContext<NotificationHub> hubContext)
          {
              _hubContext = hubContext;
          }
      }
      

      在控制器中

      public class HomeController : Controller
      {
          private readonly IHubContext<NotificationHub> _hubContext;
      
          public HomeController(IHubContext<NotificationHub> hubContext)
          {
              _hubContext = hubContext;
          }
      }
      

      拥有 HubContext 后,您可以向组/客户端等发送消息。

      public async Task SendMessage()
      {
          return await _hubContext.Clients.All.SendAsync("Notify", $"Hello world");
      }
      

      【讨论】:

        猜你喜欢
        • 2020-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-09
        • 2020-03-11
        • 1970-01-01
        相关资源
        最近更新 更多