【问题标题】:Get Hub Context in SignalR Core from within another object从另一个对象中获取 SignalR Core 中的集线器上下文
【发布时间】:2018-07-01 18:48:16
【问题描述】:

我正在使用Microsoft.AspNetCore.SignalR(最新版本)并希望从另一个不是Controller 的对象中获取集线器上下文。在“完整”的 SignalR 中,我可以使用 GlobalHost.ConnectionManager.GetHubContext<MyCoolHub>();

我已经看到了很多将Microsoft.AspNetCore.SignalR.IHubContext<MyCoolHub> 作为参数添加到Controller 的Ctor 的示例,但没有其他示例(有效)。

预计到达时间:

所以,这就是我的工作。这是 hacky 吗?

public class MyHub : Hub
    public static IHubContext<MyHub> GlobalContext { get; private set; }
    public MyHub(IHubContext<MyHub> ctx){
        GlobalContext = ctx;
    }
}

那我可以这样称呼它:

await MyHub.GlobalContext.Clients.All.InvokeAsync(...)

【问题讨论】:

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


【解决方案1】:

所以在从接受的答案中查看this example 之后,我不太明白他要去哪里,所以我尝试了一些事情,我想我明白了他在说什么。因此,对于将来遇到此问题的人,我想将该示例更改为一个完整的示例。

所以我们要创建一个“共享方法”,如示例中所示:

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace YouDontNeedToKnow.Core.Main.Hubs
{
    internal class HubMethods<THub> where THub : Hub
    {
        private readonly IHubContext<THub> _hubContext;

        public HubMethods(IHubContext<THub> hubContext)
        {
            _hubContext = hubContext;
        }

        public Task InvokeOnGroupAsync(string groupName, string method, params object[] args) =>
            _hubContext.Clients.Group(groupName).InvokeAsync(method, args);

        public Task InvokeOnAllAsync(string method, params object[] args) =>
            _hubContext.Clients.All.InvokeAsync(method, args);

        public Task AddConnectionIdToGroupAsync(string connectionId, string groupName) =>
            _hubContext.Groups.AddAsync(connectionId, groupName);

        // ...
    }
}

然后,在您的 Hub 对象中,添加一个构造函数,如下所示:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace YouDontNeedToKnow.Core.Main.Hubs
{
    internal class MyHub : Hub
    {
        public static string HubName => "myHub";

        private readonly HubMethods<MyHub> _hubMethods;

        public PlayerServicesHub(HubMethods<MyHub> hubMethods)
        {
            _hubMethods = hubMethods;
        }

        public override Task OnConnectedAsync()
        {
            return base.OnConnectedAsync();
        }
    }
}

在您的Startup.cs 中,您可以像这样注入共享类:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<HubMethods<MyHub>>();
    services.AddSignalR();
    services.AddMvc();
}

这仍然可以正常工作:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider sp)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();
    app.UseSignalR(routes =>
    {
        routes.MapHub<MyHub>(MyHub.HubName);
    });
    app.UseMvc();
    // This is just an example line of how you can get the hub with context:
    var myHub = sp.GetService<HubMethods<MyHub>>();
}

【讨论】:

    【解决方案2】:

    只需在调用方构造函数上设置IHubContext&lt;MyHub&gt; hubContext

    我建议使用 .net core 默认的 DI 容器机制,而不是创建静态属性。

    请参考How do I get a reference to a Hub?

    public class MyHub : Hub
    {
    }
    
    public class CallingSideClass
    {
        private readonly IHubContext<MyHub> _hubContext;
    
        public CallingSideClass(IHubContext<MyHub> hubContext)
        {
            _hubContext = hubContext;
        }
    
        public async Task FooMethod(...)
        {
            await _hubContext.Clients.All.InvokeAsync(...);
        }
    }
    
    public class Startup
    {...
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSignalR();
            services.AddScoped<CallingSideClass>();
        }
        ... 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-15
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 2023-03-21
      • 2015-02-02
      • 1970-01-01
      相关资源
      最近更新 更多