How to get SignalR Hub Context in a ASP.NET Core?
Solution 1
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>();
}
.....
Solution 2
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
Solution 3
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://docs.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.
Solution 4
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!
Solution 5
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>();
Admin
Updated on August 30, 2021Comments
-
Admin over 2 years
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?
-
Jakub Wisniewski almost 8 yearsThis used to work in RC1 but does not work in RC2 (I get error) - do you know how to fix it?
-
stibay almost 8 yearsHow can you find the connManager somewhere else? Don't you have to inject or refrence it somehow since its not static?
-
Bill Shihara almost 8 yearsAs 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.
-
SHM almost 7 yearshi, where did you get these information. i could not find docs after hours of searching. thanks..
-
Andrew Nikolin over 6 yearsHi! Can you please post an example of how do you register HubContext class in IoC container?
-
Suren over 6 years@AndrewNikolin, not need to register
HubContext
. just introduce your Hub inConfigure
method.app.UseSignalR(routes => { routes.MapHub<LiveHub>("live"); });
l think byservices.AddSignalR();
the HubContext would be registered automatically ... -
lenniep over 6 yearsThanks, 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? -
Suren over 6 years@lenniep
HubContext
is reachable whereverIServiceProvider
is available. you could get access toIServiceProvider
in static class by some tip and tricks but it's not recommended at all. -
lenniep over 6 years@Soren makes sense, thanks a lot. I will avoid this since I agree it's rather bad design. This has helped me as well: blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern
-
Glen Little about 6 years@BillShihara - did you resolve the problem you mentioned here?
-
santu47 over 5 yearsfor me, connections is coming empty with this code snippet. Any help!!
-
Niklas almost 5 yearsi was thinking as if i have to actually implement the
IHubContext<MyHub>
and then inject that using DI but then i realized i'd have to implementClients
andGroups
etc, but reading the comments i realized thatservices.AddSignalR();
actually injectsIHubContext<MyHub>
by default so it saved me alot of frustration! documentation isn't clear on this to my knowledge. thanks to @Soren ! -
Aaron over 4 yearsThank you so much. This was exactly what I needed to do to get SignalR working from background (hangfire) jobs
-
William Jockusch about 4 years@Soren that works unless the Hub has other dependencies, i.e. on MyApi.
-
user2475096 about 3 yearsfor .net 5 await _hubContext.Clients.All.SendAsync("yourmethod", yourparameters);
-
Dharmesh Tailor almost 2 yearsI 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".