2

I want to send messages from the server (from a class, not a controller) via the SignalR Hub.

The hub works for messages originating from the client but not for messages from the server.

I've tried multiple methods of which non seem to work. For example, I tried retrieving the hub context using: GlobalHost.ConnectionManager.GetHubContext<MyHub>() with no success.

What is the best and up-to-date method of doing this in .NET Core?

Temporary Solution:

Having a websocket client inside the host api. Then making it connect to itself. This is not an ideal solution but works as a temporary fix.

Kamkos
  • 21
  • 1
  • 4
  • Possible duplicate of [In ASP.NET Core SignalR, how do I send a message from the server to a client?](https://stackoverflow.com/questions/50788100/in-asp-net-core-signalr-how-do-i-send-a-message-from-the-server-to-a-client) – pavinan Sep 26 '19 at 17:27

2 Answers2

1

You can inject the context in your class as service. Your class must be initialized via DI and added as a service. There is no difference between class or controller.

public class SomeClass
{
    public IHubContext<ChatHub, IChatClient> _strongChatHubContext { get; }

    public SomeClass(IHubContext<ChatHub, IChatClient> chatHubContext)
    {
        _strongChatHubContext = chatHubContext;
    }

    public async Task SendMessage(string message)
    {
        await _strongChatHubContext.Clients.All.ReceiveMessage(message);
    }
}

You can also get service like following by injecting IHttpContextAccessor

var _strongChatHubContext = httpContextAccessor.HttpContext.RequestServices.GetRequiredService<IHubContext<ChatHub, IChatClient>>()

reference: https://learn.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-2.1

pavinan
  • 1,275
  • 1
  • 12
  • 23
0

First you need to somewhere instantiate your hub (normally when your app is bootstrapping).

MyHub myHub = new MyHub();

Then on your class inject the context:

private readonly IHubContext<NotifyHub, ITypedHubClient> hubContext;

And in your class method just call the hub:

hubContext.Clients.All.yourHubMethod(yourPayload);
Kiril1512
  • 3,231
  • 3
  • 16
  • 41
  • When I attempt to do it ths way I run into a problem fail: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[8] Failed to invoke hub method 'SendMessage'. – Kamkos Sep 26 '19 at 14:03
  • I believe this is because the Hub class gets 'upgraded' to IHub and requires me to implement additional classes such as OnConnected() which contain no code over than a exception throw. I can't seem to find any documentation on how to implement these methods either. – Kamkos Sep 26 '19 at 14:06
  • Are you using .NET > 4.5 or .NET Core? – Kiril1512 Sep 26 '19 at 14:14
  • .NET Core. I took GlobalHost from a .NET library as it is not working with the .NET Core libraries (doesn't even show). – Kamkos Sep 26 '19 at 14:25
  • since its .NET Core I will update my answer to the injected hub. You can try this instead: ```private readonly IHubContext hubContext;``` – Kiril1512 Sep 26 '19 at 14:28