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á
awaitse 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(...)awaitmetodaSendAsynccentra.
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 Hub má Clients 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:
SendMessageodešle zprávu všem připojeným klientům pomocíClients.All.SendMessageToCallerodešle zprávu zpět volajícímu pomocíClients.Caller.SendMessageToGroupodešle zprávu všem klientům veSignalR Usersskupině.
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.