Použití center v SignalR pro ASP.NET Core

Podle Jejich námětů a Přednášek

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

Co je SignalR centrum

Rozhraní SignalR API služby Hubs umožňuje volat metody na připojených klientech ze serveru. V kódu serveru definujete metody, které jsou volány klientem. V kódu klienta definujete metody, které jsou volány ze serveru. SignalR se postará o všechno na pozadí, což umožňuje komunikaci mezi klientem a serverem v reálném čase.

Konfigurace SignalR center

Middleware SignalR vyžaduje některé služby, které jsou nakonfigurované voláním services.AddSignalR .

services.AddSignalR();

Při přidávání funkcí do ASP.NET Core aplikace na nastavení tras voláním ve SignalR SignalR endpoint.MapHub Startup.Configure zpětném volání app.UseEndpoints metody.

app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapHub<ChatHub>("/chathub");
});

Při přidávání SignalR funkcí do ASP.NET Core aplikace na nastavení tras SignalR voláním metody app.UseSignalR Startup.Configure .

app.UseSignalR(route =>
{
    route.MapHub<ChatHub>("/chathub");
});

Vytváření a používání center

Vytvořte centrum deklarováním třídy, která dědí z , a přidejte do ní Hub veřejné metody. Klienti mohou volat metody, které jsou definovány jako public .

public class ChatHub : Hub
{
    public Task SendMessage(string user, string message)
    {
        return Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

Návratový typ a parametry, včetně komplexních typů a polí, můžete zadat stejně jako v jakékoli metodě jazyka C#. SignalR zpracovává serializaci a deserializaci komplexních objektů a polí v parametrech a návratových hodnot.

Poznámka

Centra jsou přechodná:

  • Neukládejte stav ve vlastnosti ve třídě centra. Každé volání metody centra se provádí v nové instanci centra.
  • Používá await se při volání asynchronních metod, které závisí na tom, že centrum zůstává v živém režimu. Například metoda jako může selhat, pokud je volána bez a před dokončením se dokončí Clients.All.SendAsync(...) await metoda SendAsync centra.

Kontextový objekt

Třída Hub má vlastnost , která obsahuje následující vlastnosti s informacemi o Context připojení:

Vlastnost Popis
ConnectionId Získá jedinečné ID pro připojení přiřazené pomocí SignalR . Každé připojení má jedno ID připojení.
UserIdentifier Získá identifikátor uživatele. Ve výchozím SignalR nastavení používá z přidružené k připojení jako identifikátor ClaimTypes.NameIdentifier ClaimsPrincipal uživatele.
User Získá přidružený ClaimsPrincipal k aktuálnímu uživateli.
Items Získá kolekci klíč/hodnota, kterou lze použít ke sdílení dat v rámci oboru tohoto připojení. Data mohou být uložena v této kolekci a budou zachována pro připojení napříč různými voláními metod centra.
Features Získá kolekci funkcí dostupných v připojení. Tato kolekce se zatím ve většině scénářů nepotřebuje, takže zatím není podrobně zdokumentovaná.
ConnectionAborted Získá, CancellationToken který upozorní, když je připojení přerušeno.

Hub.Context obsahuje také následující metody:

Metoda Popis
GetHttpContext Vrátí HttpContext pro připojení, nebo null pokud připojení není přidruženo k požadavku HTTP. U připojení HTTP můžete tuto metodu použít k získání informací, jako jsou hlavičky PROTOKOLU HTTP a řetězce dotazů.
Abort Přeruší připojení.

Objekt Clients

Třída HubClients vlastnost, která obsahuje následující vlastnosti pro komunikaci mezi serverem a klientem:

Vlastnost Popis
All Volá metodu na všech připojených klientech.
Caller Zavolá metodu na klientovi, která vyvolala metodu centra.
Others Zavolá metodu na všech připojených klientech s výjimkou klienta, který tuto metodu vyvolal.

Hub.Clients obsahuje také následující metody:

Metoda Popis
AllExcept Volá metodu na všech připojených klientech s výjimkou zadaných připojení.
Client Volá metodu na konkrétním připojeném klientovi.
Clients Volá metodu na konkrétních připojených klientech.
Group Zavolá metodu pro všechna připojení v zadané skupině.
GroupExcept Volá metodu pro všechna připojení v zadané skupině s výjimkou zadaných připojení.
Groups Volá metodu pro více skupin připojení.
OthersInGroup Zavolá metodu pro skupinu připojení s výjimkou klienta, který vyvolal metodu centra.
User Volá metodu pro všechna připojení přidružená ke konkrétnímu uživateli.
Users Volá metodu pro všechna připojení přidružená k zadaným uživatelům.

Každá vlastnost nebo metoda v předchozích tabulkách vrací objekt s SendAsync metodou . Metoda umožňuje zadat název a parametry metody SendAsync klienta, která se má volat.

Odesílání zpráv klientům

Pokud chcete volat konkrétní klienty, použijte vlastnosti Clients objektu . V následujícím příkladu jsou tři metody centra:

  • SendMessage odešle zprávu všem připojeným klientům pomocí Clients.All .
  • SendMessageToCaller odešle zprávu zpět volajícímu pomocí Clients.Caller .
  • SendMessageToGroup odešle zprávu všem klientům ve SignalR Users skupině.
public Task SendMessage(string user, string message)
{
    return Clients.All.SendAsync("ReceiveMessage", user, message);
}

public Task SendMessageToCaller(string user, string message)
{
    return Clients.Caller.SendAsync("ReceiveMessage", user, message);
}

public Task SendMessageToGroup(string user, string message)
{
    return Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
}

Rozbočovače silného typu

Nevýhodou použití je, že při určení klientské metody, která se má volat, spoléhá na magický SendAsync řetězec. To ponechá kód otevřený pro běhové chyby, pokud je název metody v klientovi chybně zadán nebo chybí.

Alternativou k použití SendAsync je silného typu Hub s Hub<T> . V následujícím příkladu byly klientské metody ChatHub extrahovány do rozhraní s názvem IChatClient .

public interface IChatClient
{
    Task ReceiveMessage(string user, string message);
}

Toto rozhraní lze použít k refaktoringu předchozího ChatHub příkladu.

public class StronglyTypedChatHub : Hub<IChatClient>
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.ReceiveMessage(user, message);
    }

    public Task SendMessageToCaller(string user, string message)
    {
        return Clients.Caller.ReceiveMessage(user, message);
    }
}

Použití příkazu umožňuje kontrolu klientských metod za Hub<IChatClient> kompilace. Tím se zabrání problémům způsobeným použitím magických řetězců, protože může poskytnout přístup pouze k metodám Hub<T> definovaným v rozhraní.

Použití silného Hub<T> typu zakáže možnost používat SendAsync . Všechny metody definované v rozhraní lze i nadále definovat jako asynchronní. Ve skutečnosti by každá z těchto metod měla vrátit Task . Vzhledem k tomu, že se jedná o rozhraní, nepoužívejte klíčové async slovo . Příklad:

public interface IClient
{
    Task ClientMethod();
}

Poznámka

Přípona není z názvu metody Async oříznutá. Pokud není vaše metoda klienta definovaná pomocí , neměli .on('MyMethodAsync') byste jako název používat MyMethodAsync .

Změna názvu metody centra

Ve výchozím nastavení je název metody centra serveru názvem metody .NET. Ke změně tohoto výchozího nastavení a ručnímu zadání názvu metody však můžete použít atribut HubMethodName. Klient by měl při volání metody použít tento název místo názvu metody .NET.

[HubMethodName("SendMessageToUser")]
public Task DirectMessage(string user, string message)
{
    return Clients.User(user).SendAsync("ReceiveMessage", user, message);
}

Zpracování událostí pro připojení

Rozhraní SignalR API služby Hubs poskytuje virtuální metody OnConnectedAsync a pro správu a sledování OnDisconnectedAsync připojení. Přepsáním virtuální metody proveďte akce, když se klient připojí k centru, například ji OnConnectedAsync přidejte do skupiny.

public override async Task OnConnectedAsync()
{
    await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
    await base.OnConnectedAsync();
}

Přepsáním OnDisconnectedAsync virtuální metody proveďte akce, když se klient odpojí. Pokud se klient záměrně odpojí (například voláním , bude connection.stop() exception parametr null . Pokud je ale klient odpojený kvůli chybě (například kvůli selhání sítě), bude parametr obsahovat výjimku exception popisující selhání.

public override async Task OnDisconnectedAsync(Exception exception)
{
    await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
    await base.OnDisconnectedAsync(exception);
}

Upozornění

Upozornění zabezpečení: vystavení ConnectionId může způsobit škodlivou zosobnění, pokud SignalR je verze serveru nebo klienta ASP.NET Core 2,2 nebo starší.

Ošetření chyb

Výjimky vyvolané metodami centra se odesílají klientovi, který tuto metodu vyvolal. V klientovi JavaScriptu invoke vrátí metoda příslib JavaScriptu. Když klient obdrží chybu s obslužnou rutinou připojenou k příslibu pomocí , vyvolá se catch a předá jako objekt JavaScriptu. Error

connection.invoke("SendMessage", user, message).catch(err => console.error(err));

Pokud vaše centrum vyvolá výjimku, připojení se nezavře. Ve výchozím SignalR nastavení vrátí klientovi obecnou chybovou zprávu. Příklad:

Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'MethodName' on the server.

Neočekávané výjimky často obsahují citlivé informace, například název databázového serveru ve výjimce aktivované při selhání připojení k databázi. SignalR nezpřístupňuje tyto podrobné chybové zprávy ve výchozím nastavení jako bezpečnostní opatření. Další informace o tom, proč jsou podrobnosti o výjimce potlačeny, najdete v článku Důležité informace o zabezpečení.

Pokud máte výjimečnou podmínku, kterou chcete rozšířit do klienta, můžete použít HubException třídu . Pokud z metody centra vyvoláte výjimku , odešle klientovi celou zprávu HubException SignalR v nezměněném formátu.

public Task ThrowException()
{
    throw new HubException("This error will be sent to the client!");
}

Poznámka

SignalR odešle pouze Message vlastnost výjimky klientovi. Trasování zásobníku a další vlastnosti výjimky nejsou pro klienta k dispozici.