55

I'm trying to get the context for a hub using the following:

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

The problem is that GlobalHost is not defined. I see it is part of the SignalR.Core dll. At the moment, I have the following in my project .json file, under dependencies:

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

If I add the latest available version of Core:

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

I get a whole bunch of errors because server and core are conflicting. If I change them to both use version "3.0.0-*", all the conflicts go away, but GlobalHost cannot be found. If I remove Server, and just user Core version 2.1.2 then GlobalHost works, but all the other things needing Server, obviously do not.

Any ideas?

1
  • Current solution provided in this answer to a similar question. Commented Mar 8, 2017 at 22:35

6 Answers 6

107

IConnectionManager does not exist any more in SignalR for ASP.Net Core.
I've been using HubContext for getting access to a hub.

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);
    }
}

I'm using .net core 2.0.0 and SignalR 1.0.0-alpha1-final

Sign up to request clarification or add additional context in comments.

9 Comments

Hi! Can you please post an example of how do you register HubContext class in IoC container?
@AndrewNikolin, not need to register HubContext. just introduce your Hub in Configure method. app.UseSignalR(routes => { routes.MapHub<LiveHub>("live"); }); l think by services.AddSignalR(); the HubContext would be registered automatically ...
Thanks, that helped a lot. But how would I access the HubContext from outside a controller? Is there a way to call a hub method also from a static context?
@lenniep HubContext is reachable wherever IServiceProvider is available. you could get access to IServiceProvider in static class by some tip and tricks but it's not recommended at all.
for .net 5 await _hubContext.Clients.All.SendAsync("yourmethod", yourparameters);
|
25

Microsoft.AspNet.SignalR.Infrastructure.IConnectionManager is a DI injected service through which you can get the hub context...For example:

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 Comments

This used to work in RC1 but does not work in RC2 (I get error) - do you know how to fix it?
hi, where did you get these information. i could not find docs after hours of searching. thanks..
10

To use the hub in a backgroud service, in addition to controllers, you must use the IHostedService interface and get the hub by 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()
    {
    }
}

Then you can call your hub from anywhere in your code from HubContext static field:

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

Learn more about IHostedService: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1

You can create and start a timer in MyBackgroundService and call the hub in ElapsedEvent.

1 Comment

Thank you so much. This was exactly what I needed to do to get SignalR working from background (hangfire) jobs
2

I added some code to my Startup.cs to grab reference to the ConnectionManager which you can then use to do a GetHubContext at anytime from anywhere in your code. Similar to Nimo's answer but a little different, maybe simpler.

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 Comments

How can you find the connManager somewhere else? Don't you have to inject or refrence it somehow since its not static?
As of the latest build, 0.0.2-alpha1-21709, this technique no longer works. I create a static variable for IConnectionManager in the startup class. When it is referenced in another class, the IHubContext is available but hub.Clients.All.SendMessage("foo") does not send a message to the clients.
@BillShihara - did you resolve the problem you mentioned here?
2

I needed to be able to access the Hub Context from outside the app request thread - because I was subscribing to NServicebus messages, and needed to be able to trigger a client function when I received a message.

Here's how I got it sorted:

public static IServiceProvider __serviceProvider;

then during startup configuration

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

Then anywhere else in the vNext asp.net application (any other thread)

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

Hope this helps!

Comments

1

I'm looking at SignalR source code and it seems that IHubContext is registered as a singleton.

Which means you get the same instance whenever you access it.

Which means you can simply save it in a static var and use it from whatever.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHubContext<MyHub> hubContext)
{
    _staticVar = hubContext;
}

But be warned - it's an anti-pattern.

1 Comment

I also wanted to use it within NServiceBus handler. End up following what @RenanStr suggested. works like a charm. But when you think about it, it's not something different to what you suggested "Static HubContext".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.