Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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(..)
like image 224
sports Avatar asked Jun 30 '13 21:06

sports


People also ask

How does SignalR hub work?

The SignalR Hubs API enables you to call methods on connected clients from the server. In the server code, you define methods that are called by client. In the client code, you define methods that are called from the server.

What is IHubContext?

The IHubContext is for sending notifications to clients, it is not used to call methods on the Hub . View or download sample code (how to download)

What is HUB in Azure SignalR?

In SignalR, a hub is a core component that exposes a set of methods that can be called by the client. In this section, you define a hub class with two methods: Broadcast : This method broadcasts a message to all clients. Echo : This method sends a message back to the caller.


2 Answers

The correct way is to actually create the hub context. How and where you do that is up to you, here are two approachs:

  1. 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);
    }
    
  2. 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);
    
like image 69
N. Taylor Mullen Avatar answered Oct 19 '22 06:10

N. Taylor Mullen


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://learn.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();
}
like image 5
Jack Avatar answered Oct 19 '22 06:10

Jack