如何在ASP.NET核心中获取SignalR Hub上下文?

时间:2014-12-04 16:40:38

标签: signalr signalr-hub asp.net-core

我正在尝试使用以下内容获取集线器的上下文:

var hubContext = GlobalHost.ConnectionManager.GetHubContext<SomeHub>();

问题在于没有定义GlobalHost。我看到它是SignalR.Core dll的一部分。目前,我的项目.json文件中包含以下依赖项:

"Microsoft.AspNet.SignalR.Server": "3.0.0-*"

如果我添加最新版本的Core:

"Microsoft.AspNet.SignalR.Server": "3.0.0-*",
"Microsoft.AspNet.SignalR.Core" :  "2.1.2"

我得到了一大堆错误,因为服务器和核心存在冲突。如果我将它们更改为使用版本“3.0.0- *”,则所有冲突都会消失,但无法找到GlobalHost。如果我删除Server,只删除用户Core版本2.1.2然后GlobalHost工作,但所有其他需要Server的东西,显然不会。

有什么想法吗?

5 个答案:

答案 0 :(得分:68)

对于ASP.Net Core, SignalR

IConnectionManager不再存在。
我一直在使用HubContext来访问集线器。

public class HomeController : Controller
{
    private readonly IHubContext<LiveHub> _hubContext;

    public HomeController(IHubContext<LiveHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public void SendToAll(string message)
    {
        _hubContext.Clients.All.InvokeAsync("Send", message);
    }
}
  

我正在使用.net core 2.0.0和SignalR 1.0.0-alpha1-final

答案 1 :(得分:19)

Microsoft.AspNet.SignalR.Infrastructure.IConnectionManager是一个DI注入服务,您可以通过该服务获取集线器上下文...例如:

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Infrastructure;
using Microsoft.AspNet.Mvc;

public class TestController : Controller
{
     private IHubContext testHub;

     public TestController(IConnectionManager connectionManager)
     {
         testHub = connectionManager.GetHubContext<TestHub>();
     }
 .....

答案 2 :(得分:2)

我在Startup.cs中添加了一些代码来获取对ConnectionManager的引用,然后您可以随时在代码中的任何位置使用它来执行GetHubContext。类似于Nimo的答案,但有点不同,也许更简单。

services.AddSignalR(options =>
{
    options.Hubs.EnableDetailedErrors = true;
});

var provider = services.BuildServiceProvider();

//Hold on to the reference to the connectionManager
var connManager = provider.GetService(typeof(IConnectionManager)) as IConnectionManager;

//Use it somewhere else
var hub = connManager.GetHubContext<SignalHub>();

答案 3 :(得分:2)

要在背景服务中使用集线器,除了控制器外,还必须使用IHostedService接口并通过DI获取集线器。

public class MyBackgroundService : IHostedService, IDisposable
{
    public static IHubContext<NotifierHub> HubContext;

    public MyBackgroundService(IHubContext<NotifierHub> hubContext)
    {
        HubContext = hubContext;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        //TODO: your start logic, some timers, singletons, etc
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        //TODO: your stop logic
        return Task.CompletedTask;
    }

    public void Dispose()
    {
    }
}

然后,您可以从HubContext静态字段中的代码中的任何位置调用集线器:

MyBackgroundService.HubContext.Clients.All.SendAsync("UpdateData", myData).Wait();

了解有关IHostedService的更多信息: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1

您可以在MyBackgroundService中创建和启动计时器,并在ElapsedEvent中调用集线器。

答案 4 :(得分:1)

我需要能够从app请求线程外部访问Hub Context - 因为我订阅了NServicebus消息,并且在收到消息时需要能够触发客户端功能。

这是我如何排序的:

public static IServiceProvider __serviceProvider;

然后在启动配置期间

app.UseServices(services =>
        {
            __serviceProvider = new ServiceCollection()
            .BuildServiceProvider(CallContextServiceLocator.Locator.ServiceProvider);
        });

然后在vNext asp.net应用程序中的任何其他位置(任何其他线程)

 var manager = Startup.__serviceProvider.GetRequiredService<IConnectionManager>();
            var hub = manager.GetHubContext<ChatHub>();

希望这有帮助!