Access to signalr hub from other part of my application

Solution for Access to signalr hub from other part of my application
is Given Below:

I am writing a blazor server web app.

I have wrote this very basic signalr hub:

using Microsoft.AspNetCore.SignalR;

public class MyHub: Hub
{
   public override Task OnConnectedAsync()
   {
      ...
      return base.OnConnectedAsync();
   }

   public Task my_function()
   {
      ...
   }
   ....
}

It works fine at this step.

Now, i want to access to this hub from another part of my blazor application:

public class AnotherClass
{
   private readonly IHubContext<MyHub> _hub;

   public AnotherClass(IHubContext<MyHub> hub)
   {
      _hub = hub;
   }

   ...
   
   public void another_function()
   {
      _hub.Clients.All.SendAsync(...); // <- This line works fine
      (_hub as MyHub).my_function();   // <- Does not work
   }
}

As you can see, i am working with dependency injection to access to my hub object.
I have read a lot of documentation, including Microsoft’s official documentation.
Everybody says we have to work with IHubContext type in this kind of dependency injection.

So _hub object does not know my_function method…

I have tried a lot of things:

  • Cast _hub to MyHub
  • Declare a IMyHub interface and work with IMyHub in dependency injection
  • etc.

Nothing works…

My question is: How can i call my_function from AnotherClass object ?

Thanks a lot

How can i call my_function from AnotherClass object ?

You can’t. The Hub is only called in response to a client invocation. There is no way to call a hub method manually.

If there is logic you want to run both inside the hub and outside the hub, you will need to refactor your code so it is some shared class that the Hub and AnotherClass can access.

Here’s how I did it.

Create an interface for your hub:

public interface IMyHub
{
    Task MyFunction(int parameter);
}

Then your hub implements the interface like so:

public class MyHub : Hub<IMyHub>
{
    public async Task MyFunction(int parameter)
    {
        // do stuff
    }
}

Then inject the hub into other classes like so:

private readonly IHubContext<MyHub, IMyHub> _myHub;

And you can invoke your function via:

_myhub.Clients.All.MyFunction(someInt);

This is based on the Strongly Typed Hubs and Send Messages From Outside a Hub documentation.

Functions you add to your IMyHUb interface don’t necessarily have to have implementation code in the MyHub class. For instance, with

public interface IMyHub
{
    Task MyFunction(int parameter);
    Task MySecondFunction();
}

in your other class you can invoke

_myhub.Clients.All.MySecondFunction();

without any new code in the MyHub class.