5
votes

I'm working with a project built with ASP.NET Core 2.2. The main solution contains multiple projects, which includes API, web and other class libraries.

We've used SignalR to displaying shared messages/notifications between the API project and the web project. For example, adding a new employee record from an API should call SignalR Hub and all the web client should received the notification.

Here is the current structure of our project

|- API
|- Hub_ClassLibrary
|- Services
|- Web

Flow:

Web > services > Hub 
API > services > Hub

Hub:

public class NotificationHub : Hub
{
    public async Task SendNotification(List<DocumentHistoryModel> notifications)
    {
        await Clients.All.SendAsync(Constants.ReceiveNotification, notifications);
    }
}

Web startup class:

app.UseSignalR(routes =>
{
    routes.MapHub<NotificationHub>("/notificationHub");
});

API startup class

app.UseSignalR(routes =>
{
    routes.MapHub<NotificationHub>("/notificationHub");
});

Service

private readonly IHubContext<NotificationHub> _hubContext;

public MyService(IHubContext<NotificationHub> hubContext)
{
    _hubContext = hubContext;
}

await _hubContext.Clients.All.SendAsync(ReceiveNotification, notifications);

The issue is, I can send and receive notifications from web, but from api call, web doesn't get any notification. I think problem is it creates two separate connections for each project, but then what is the best way to handle this kind of scenario?

Edit: I can get connection id and state "connected" in this api code, however, web is still not receiving any notification. Also tried connection.InvokeAsync

var connection = new HubConnectionBuilder()
     .WithUrl("https://localhost:44330/notificationhub")
     .Build();

connection.StartAsync().ContinueWith(task =>
{
    if (task.IsFaulted)
    {                    
    }
    else
    {                    
        connection.SendAsync("UpdateDashboardCount", "hello world");
    }
}).Wait();

enter image description here

2
Are they sharing same host? Both Web and API?Kiril1512
Nope, host are different for both @Kiril1512Divyang Desai
host are different for both: So there will be two hubs? IMO it's better to have only one Hub: 1. Create a HubClient to push notifications to Hub? 1. Or as an alternative, use a sub/pub way like RabbitMQ/Redis sub/pub?itminus
@itminus, So there will be two hubs? There is only one hub in a class library. But want to use in different project having same DB. Not sure about how to create such mechanism.Divyang Desai
@Div you can choose to use Azure SignalR so you can redirect to it in your both cases.Kiril1512

2 Answers

0
votes

For this senario you are better off using pub/sub systems such as rabbitmq, kafka, akka.net, redis. However, if you insist on using signalr, the best solution would be to create a message coordinator with signalr and make it signalr host and then your other services would act as clients that sends their message to that signalr service and receive messages from that (you may even need to implement some logic for making your massage coordinator to queue messages and make them persistant) Besides, if you can migrate to asp.net core 3 you should definitally checkout grpc bi-directional streaming as well which can be a perfect solution to your problem.

0
votes

you can inject your HubContext into your controller in API project and try hitting 'InvokeAsync'