Accessing a hubcontext instance in asp.net core signalr

i’m following a guide for setting up signalr for my asp.net core project.

While following this guide, I have this snippet of code:

void SendMessage(string message)
{
   GlobalHost
  .ConnectionManager
  .GetHubContext<NotificationHub>().Clients.sendMessage(
message);
}

I have a NotificationHub file that looks like so:

public class NotificationHub : Hub
{
    public string Activate()
    {
        return "Monitor Activated";
    }
}

Globalhost is used to get a Hubcontext object.
The issue is that When I import signalR, nothing called GlobalHost is available. In the documentation I can find this info about it:

GlobalHost

ASP.NET Core has dependency injection (DI) built into the framework. Services can use DI to 
access the HubContext. The GlobalHost object that is used in ASP.NET SignalR to get a HubContext 
doesn't exist in ASP.NET Core SignalR.

ok, so Globalhost is simply not available in core.

I need to do the same code, but for Microsoft.AspNetCore.SignalR;.

How can I get a hold of a Hubcontext object now?

EDIT

I have now tried following the very minimal example from the documentation, and create a small sample project.
My “startup.csfile has this line, inConfigureServices`:

services.AddSignalR();

and this line in Configure:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<NotificationHub>("/Hubs");
    });

and my Hub file looks like this, as seen in the documentation:

namespace mvcCoreSample.Hubs
{
    public class NotificationHub : Hub
    {
        public Task SendMessage(string user, string message)
        {
            return Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

Where Hubs, is a folder in the same directory as startup.cs.
I have a controller that looks like this, which calls the hub:

public class msgController : Controller
{
    public IActionResult Index()
    {
        NotificationHub hub = new NotificationHub();
        hub.SendMessage("user1", "some message");
        return Content("serving content");
    }
}

But when I run this, and go to the url of the controller, the hub throws an error in the sendmessage function:

Microsoft.AspNetCore.SignalR.Hub.Clients.get returned null.

I really can’t see where I am going wrong, something must be missing from the hub? perhaps something with setting up a connection?

EDIT 2

After a few corrections, I changed my controller to look like this:

public IActionResult Index(IHubContext<NotificationHub> hub)
{
    var clients = hub.Clients;
    return Content("serving content");
}

Even though I still did not know how to call my sendmessage function, I wanted to try this.

When running this site in debug mode, I get this error thrown in the browser:

InvalidOperationException: Could not create an instance of type 'Microsoft.AspNetCore.SignalR.IHubContext`1[[mvcCoreSample.Hubs.NotificationHub, mvcCoreSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Alternatively, give the 'hub' parameter a non-null default value.

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

You can inject it in a constructor of your service like this:

SomeService(IHubContext<NotificationHub> hub)

You are probably looking at some old documentation. Please, check the official docs here: Use hubs in SignalR for ASP.NET Core

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply