Odesílání zpráv mimo centrum

Centrum SignalR je základní abstrakce pro odesílání zpráv klientům připojeným k SignalR serveru. Pomocí této služby je také možné odesílat zprávy z jiných míst ve vaší aplikaci IHubContext . Tento článek vysvětluje, jak získat přístup k SignalRIHubContext odesílání oznámení klientům mimo centrum.

Poznámka:

Slouží IHubContext k odesílání oznámení klientům, nepoužívá se k volání metod v objektu Hub.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Získání instance IHubContext

V ASP.NET Core SignalRmáte přístup k instanci IHubContext prostřednictvím injektáže závislostí. Instanci můžete vložit IHubContext do kontroleru, middlewaru nebo jiné služby DI. Pomocí instance můžete odesílat zprávy klientům.

Vložení instance IHubContext kontroleru

Instanci IHubContext do kontroleru můžete vložit přidáním do konstruktoru:

public class HomeController : Controller
{
    private readonly IHubContext<NotificationHub> _hubContext;

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

S přístupem k instanci IHubContextvolání metod klienta, jako byste byli v samotném centru:

public async Task<IActionResult> Index()
{
    await _hubContext.Clients.All.SendAsync("Notify", $"Home page loaded at: {DateTime.Now}");
    return View();
}

Získání instance v middlewaru IHubContext

Přístup k kanálu middlewaru IHubContext , například takto:

app.Use(async (context, next) =>
{
    var hubContext = context.RequestServices
                            .GetRequiredService<IHubContext<ChatHub>>();
    //...
    
    if (next != null)
    {
        await next.Invoke();
    }
});

Poznámka:

Pokud jsou klientské metody volána zvnějšku Hub třídy, neexistuje žádný volající přidružený k vyvolání. Proto neexistuje přístup k objektu ConnectionId, Callera Others vlastnosti.

Aplikace, které potřebují namapovat uživatele na ID připojení a zachovat mapování, můžou udělat jednu z těchto věcí:

  • Trvalé mapování jednoho nebo více připojení jako skupin Další informace najdete v SignalR tématu Skupiny.
  • Zachovejte informace o připojení a uživateli prostřednictvím jedné služby. Další informace najdete v tématu Vložení služeb do centra . Jednoúčelová služba může použít libovolnou metodu úložiště, například:
    • Úložiště v paměti ve slovníku
    • Trvalé externí úložiště. Například databáze nebo Azure Table Storage pomocí balíčku NuGet Azure.Data.Tables.
  • Předejte ID připojení mezi klienty.

Získání instance IHubContext z IHost

IHubContext Přístup z webového hostitele je užitečný pro integraci s oblastmi mimo ASP.NET Core, například pomocí architektur injektáže závislostí třetích stran:

    public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();
            var hubContext = host.Services.GetService(typeof(IHubContext<ChatHub>));
            host.Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder => {
                    webBuilder.UseStartup<Startup>();
                });
    }

Vložení hubContextu se silnými typy

Pokud chcete vložit hubContext silného typu, ujistěte se, že vaše centrum dědí z Hub<T>. Vloží ho IHubContext<THub, T> pomocí rozhraní místo IHubContext<THub>.

public class ChatController : Controller
{
    public IHubContext<ChatHub, IChatClient> _strongChatHubContext { get; }

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

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

Další informace najdete v tématu Rozbočovače se silnými typy.

Použití IHubContext v obecném kódu

Vloženou IHubContext<THub> instanci lze přetypovat na IHubContext bez zadaného obecného Hub typu.

class MyHub : Hub
{ }

class MyOtherHub : Hub
{ }

app.Use(async (context, next) =>
{
    var myHubContext = context.RequestServices
                            .GetRequiredService<IHubContext<MyHub>>();
    var myOtherHubContext = context.RequestServices
                            .GetRequiredService<IHubContext<MyOtherHub>>();
    await CommonHubContextMethod((IHubContext)myHubContext);
    await CommonHubContextMethod((IHubContext)myOtherHubContext);

    await next.Invoke();
}

async Task CommonHubContextMethod(IHubContext context)
{
    await context.Clients.All.SendAsync("clientMethod", new Args());
}

To je užitečné v těchto případech:

  • Psaní knihoven, které nemají odkaz na konkrétní Hub typ, který aplikace používá.
  • Psaní kódu, který je obecný a může se vztahovat na více různých Hub implementací

Další materiály