简体   繁体   中英

How to use shared SignalR Hub from different hosted project in ASP.NET Core 2.2

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();

在此处输入图像描述

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM