Mengirim pesan melalui SignalR HubContext dari metode dalam proyek di luar tempat Hub berada

Dec 08 2020

Saya memiliki proyek WebAPI di mana lapisan API, Layanan, dan Data semuanya berada dalam proyek terpisah dari solusi yang sama. Sebagai bagian dari metode dalam proyek Layanan saya, saya ingin mengirim pesan ke klien hub yang terhubung dalam proyek API. Sejauh ini semua contoh yang saya temukan memiliki semuanya dalam satu proyek dan menggunakan pengontrol sebagai contoh mengirim pesan melalui hub.

Saya sudah mencoba injeksi ketergantungan (Autofac) namun saya tidak bisa mendapatkan referensi ke MessageHub.

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

Upaya saya di Injecting dapat dilihat di sini: Inject SignalR IHubContext ke lapisan layanan dengan Autofac

Jawaban

1 AlexanderI. Dec 08 2020 at 04:41

Harap tinjau opsi ini:

  1. Tentukan antarmuka hub umum di proyek Lapisan Layanan (atau Domain yang lebih baik) Anda. Sesuatu seperti IMessageBroker.
  2. Di dalam proyek Presentation Layer (WebAPI) Anda, implementasikan antarmuka ini dan gunakan IConnectionManageruntuk pengambilan HubContext.
  3. Daftarkan antarmuka di Kontainer IoC (Autofac) di Lapisan Presentasi
  4. Masukkan antarmuka di dalam App Service

Kode Pseudo:

Lapisan Domain:

public interface IMessageBroker
{
    void ShowNewMessage(string message)
}

Lapisan Layanan:

public class NotificationService: INotificationService
{
    private readonly IMessageBroker _messageBroker;

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

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

Lapisan Presentasi:

[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
    }
}

Pendaftaran Autofac (Lapisan Presentasi):

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

Juga topik SO serupa tersedia di sini .