Call a hub method from a controller's action
How can I call a hub method from a controller's action? What is the correct way of doing this?
Someone used this in a post:
DefaultHubManager hd = new DefaultHubManager(GlobalHost.DependencyResolver);
var hub = hd.ResolveHub("AdminHub") as AdminHub;
hub.SendMessage("woohoo");
But for me, that is throwing:
Using a Hub instance not created by the HubPipeline is unsupported.
I've read also that you can create a hub context, but I don't want to give the responsability to the action, that is, the action doing stuff like:
hubContext.Client(...).someJsMethod(..)
The correct way is to actually create the hub context. How and where you do that is up to you, here are two approachs:
-
Create a static method in your hub (doesn't have to be in your hub, could actually be anywhere) and then you can just call it via
AdminHub.SendMessage("wooo")
public static void SendMessage(string msg) { var hubContext = GlobalHost.ConnectionManager.GetHubContext<AdminHub>(); hubContext.Clients.All.foo(msg); }
-
Avoid the static method all together and just send directly to the hubs clients
var hubContext = GlobalHost.ConnectionManager.GetHubContext<AdminHub>(); hubContext.Clients.All.foo(msg);
As per aspnet3.1
This differs from ASP.NET 4.x SignalR which used GlobalHost to provide access to the IHubContext. ASP.NET Core has a dependency injection framework that removes the need for this global singleton.
The currently suggested way to do this is by Dependency Injection. You can read more about that here.
https://docs.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-3.1
Snippet from above
public class HomeController : Controller
{
private readonly IHubContext<NotificationHub> _hubContext;
public HomeController(IHubContext<NotificationHub> hubContext)
{
_hubContext = hubContext;
}
}
Then call it like so
public async Task<IActionResult> Index()
{
await _hubContext.Clients.All.SendAsync("Notify", $"Home page loaded at: {DateTime.Now}");
return View();
}