Wysyłaj wiadomości za pośrednictwem SignalR HubContext z metody w projekcie poza miejscem, w którym znajdują się centra

Dec 08 2020

Mam projekt WebAPI, w którym warstwy API, usług i danych znajdują się w osobnych projektach tego samego rozwiązania. W ramach metody w projekcie usługi chcę wysłać wiadomość do połączonych klientów centrum w projekcie interfejsu API. Jak dotąd wszystkie przykłady, które znalazłem, mają wszystko w jednym projekcie i używają kontrolera jako przykładu wysyłania wiadomości przez hub.

Próbowałem wstrzyknąć zależności (Autofac), ale nie mogę uzyskać odniesienia do MessageHub.

[HubName("messages")]
public class MessageHub : Hub
{
    public void ShowNewMessage(string message)
    {
        Clients.All.showMessageOnPage(message);
    }
}

Moją próbę wstrzykiwania można zobaczyć tutaj: Inject SignalR IHubContext do warstwy usługowej za pomocą Autofac

Odpowiedzi

1 AlexanderI. Dec 08 2020 at 04:41

Sprawdź tę opcję:

  1. Zdefiniuj ogólny interfejs koncentratora w projekcie warstwy usługi (lub lepszej domeny). Coś jak IMessageBroker.
  2. W projekcie warstwy prezentacji (WebAPI) zaimplementuj ten interfejs i użyj go IConnectionManagerdo pobierania HubContext.
  3. Zarejestruj interfejs w kontenerze IoC (Autofac) w warstwie prezentacji
  4. Wstrzyknij interfejs wewnątrz usługi App Service

Pseudo kod:

Warstwa domeny:

public interface IMessageBroker
{
    void ShowNewMessage(string message)
}

Warstwa usług:

public class NotificationService: INotificationService
{
    private readonly IMessageBroker _messageBroker;

    public NotificationService(IMessageBroker messageBroker)
    {
        _messageBroker = messageBroker;
    }

    public void RunNotification(string message)
    {
        _messageBroker.ShowNewMessage(message);
    }
}

Warstwa prezentacji:

[HubName("messages")]
public class MessageHub: Hub
{
    public void ShowNewMessage(string message)
    {
        Clients.All.showMessageOnPage(message);
    }
}


public class MessageBroker: IMessageBroker
{
    private readonly IConnectionManager _connectionManager;

    public MessageBroker(IConnectionManager connectionManager)
    {
        _connectionManager = connectionManager;
    }

    public void ShowNewMessage(string message)
    {
        var hub = _connectionManager.GetHubContext<MessageHub>();
        // Use Hub Context and send message
    }
}

Rejestracja Autofac (warstwa prezentacji):

// Register Hubs
builder.RegisterHubs(Assembly.GetExecutingAssembly());

// Register Autofac resolver into container to be set into HubConfiguration later
builder.RegisterType<AutofacDependencyResolver>().As<IDependencyResolver>().SingleInstance();

// Register ConnectionManager as IConnectionManager so that you can get hub context via IConnectionManager injected to your service
builder.RegisterType<ConnectionManager>().As<IConnectionManager>().SingleInstance();

// Register interface
builder.RegisterType<MessageBroker>().As<IMessageBroker>();

Również podobny temat SO jest dostępny tutaj .