Jak działa ASP.NET Core SignalR
Serwery i Hub
klasa
Klasa Hub
jest koncepcją serwera SignalR. Jest ona zdefiniowana w Microsoft.AspNetCore.SignalR
przestrzeni nazw i jest częścią pakietu NuGet Microsoft.AspNetCore.SignalR . ASP.NET Core aplikacji internetowych przeznaczonych dla zestawu SDK Microsoft.NET.Sdk.Web nie trzeba dodawać odwołania do pakietu dla usługi SignalR, ponieważ jest już dostępna w ramach struktury udostępnionej.
Element A Hub
jest uwidaczniony za pośrednictwem trasy. Na przykład https://www.contoso-pizza.com/hubs/orders
trasa może służyć do reprezentowania implementacji OrdersHub
. Za pomocą różnych interfejsów API centrum autorzy mogą definiować metody i zdarzenia.
Istnieją dwa sposoby uwidaczniania metod na koncentratonie. Utworzysz podklasę następujących typów i metod zapisu:
Przykład: Hub
Jako punkt odniesienia należy wziąć pod uwagę następujący Notification
obiekt:
namespace RealTime.Models;
public record Notification(string Text, DateTime Date);
Obiekt można udostępnić podczas korzystania z zestawu SDK klienta platformy .NET, aby serwer i klient mieli dokładnie ten sam obiekt. Wyobraź sobie centrum powiadomień:
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
using RealTime.Models;
namespace ExampleServer.Hubs;
public sealed class NotificationHub : Hub
{
public Task NotifyAll(Notification notification) =>
Clients.All.SendAsync("NotificationReceived", notification);
}
Jeśli chodzi o różnicę między metodami i zdarzeniami, metoda w poprzedniej implementacji centrum to NotifyAll
, a zdarzenie to NotificationReceived
.
NotificationHub
jest podklasą .Hub
Metoda NotifyAll
zwraca wartość Task
i akceptuje pojedynczy Notification
parametr. Metoda jest wyrażona jako wywołanie z SendAsync
Clients.All
klasy , która reprezentuje wszystkich połączonych klientów. Zdarzenie NotificationReceived
jest uruchamiane w zależności od notification
wystąpienia.
IHubContext
Wystąpienie
Zdarzenia są wyzwalane z Hub
wystąpienia lub IHubContext
. Centrum SignalR to podstawowa abstrakcja wysyłania komunikatów do klientów połączonych z serwerem SignalR. Istnieje również możliwość wysyłania komunikatów z innych miejsc w aplikacji przy użyciu jednego z następujących typów:
-
IHubContext<THub>: kontekst, w którym
THub
reprezentuje standardowe centrum. -
IHubContext<THub,T>: kontekst, w którym
THub
reprezentuje silnie typizowane centrum ogólne iT
reprezentuje odpowiedni typ klienta.
Ważne
IHubContext
program służy do wysyłania powiadomień do klientów. Nie służy do wywoływania metod w obiekcie Hub
.
Przykład IHubContext
Biorąc pod uwagę poprzednią implementację centrum powiadomień, można użyć IHubContext<NotificationHub>
w następujący sposób:
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
using RealTime.Models;
namespace ExampleServer.Services;
public sealed class NotificationService(
IHubContext<NotificationHub> hubContext)
{
public Task SendNotificationAsync(Notification notification) =>
notification is not null
? hubContext.Clients.All.SendAsync("NotificationReceived", notification)
: Task.CompletedTask;
}
Powyższy kod języka C# opiera się na IHubContext<NotificationHub>
uzyskiwaniu dostępu do kontekstowej listy klientów, co umożliwia emisję powiadomień. Podstawowy hubContext
parametr konstruktora przechwycony w zakresie jest używany do wyzwalania "NotificationReceived"
zdarzenia, ale nie ma być używany do wywoływania metody centrum NotifyAll
.
Metody
Hub
lub Hub<T>
metody są tak samo jak każda inna metoda języka C#. Definiują typ zwracany, nazwę metody i parametry.
- Najczęstszym typem zwracanym dla metody koncentratora jest
Task
lubTask<TResult>
, która reprezentuje operację centrum asynchronicznego. - Nazwa metody służy do wywoływania metody z klientów. Można go dostosować przy użyciu polecenia HubMethodNameAttribute.
- Parametry są opcjonalne, ale po ich zdefiniowaniu klienci powinni podać odpowiednie argumenty.
Metody nie są wymagane do uruchamiania zdarzeń, ale często są wykonywane.
Zdarzenia
Zdarzenie można subskrybować według nazwy od klienta. Serwer jest odpowiedzialny za zgłaszanie zdarzeń.
Hub
, , Hub<T>
IHubContext<THub>
i IHubContext<THub, T>
zdarzenia są nazwane i mogą definiować maksymalnie 10 parametrów. Zdarzenia są wyzwalane na serwerze i obsługiwane przez zainteresowanych klientów. Klient jest uważany za zainteresowany, gdy subskrybuje zdarzenia w połączeniu centrum. Klienci mogą pośrednio wyzwalać zdarzenia, gdy wywołują metody centrum, które wyzwalają zdarzenia w wyniku wywołania. Zdarzenia nie mogą być jednak wyzwalane bezpośrednio przez klientów, ponieważ jest to odpowiedzialność serwera.
Zakresy klienta zdarzeń
Zdarzenia są wywoływane z IClientProxy wystąpienia. Zaimplementujesz IHubClients interfejsy i IHubCallerClients z Clients typu . Istnieje wiele sposobów, aby ograniczyć zakres do określonego IClientProxy
wystąpienia. Możesz określić następujące zakresy z Hub.Clients
właściwości :
Element członkowski | Szczegóły |
---|---|
All |
Wszyscy połączeni klienci (na przykład emisja). |
AllExcept |
Wszyscy połączeni klienci z wyłączeniem określonych połączeń (takich jak filtrowana emisja). |
Caller |
Połączony klient, który wyzwolił metodę (np. echo). |
Client |
Określone połączenie klienta (pojedyncze połączenie). |
Clients |
Określone połączenia klienta (wiele połączeń). |
Group |
Wszyscy połączeni klienci w określonej grupie. |
GroupExcept |
Wszyscy połączeni klienci w określonej grupie z wyłączeniem określonych połączeń. |
Groups |
Wszyscy połączeni klienci w ramach określonych grup (wiele grup). |
Others |
Wszyscy połączeni klienci z wyłączeniem klienta, który wyzwolił metodę. |
OthersInGroup |
Wszyscy połączeni klienci w określonej grupie z wyłączeniem klienta, który wyzwolił metodę. |
User |
Wszyscy połączeni klienci dla określonego użytkownika (jeden użytkownik może nawiązać połączenie na więcej niż jednym urządzeniu). |
Users |
Wszyscy połączeni klienci dla określonych użytkowników. |
Przykładowe zakresy
Rozważmy poniższe obrazy, które mogą ułatwić wizualizowanie sposobu wysyłania komunikatów przez centrum do docelowych klientów. Obrazy można rozszerzyć, aby zwiększyć czytelność.
Rozgłoś do wszystkich
Wszyscy połączeni klienci otrzymują ten komunikat niezależnie od grupy, do której mogą należeć lub nie należą.
Izolowany użytkownik
Jeden użytkownik otrzymuje ten komunikat niezależnie od liczby aktualnie używanych urządzeń.
Grupa izolowana
Ten komunikat otrzymują tylko klienci należący do określonej grupy.
Klienci i HubConnection
klasa
Klasa HubConnection
jest koncepcją klienta usługi SignalR, która reprezentuje połączenie klienta z serwerem Hub
. Jest ona zdefiniowana w Microsoft.AspNetCore.SignalR.Client
przestrzeni nazw i jest częścią pakietu NuGet Microsoft.AspNetCore.SignalR.Client .
Element można HubConnection
utworzyć przy użyciu wzorca konstruktora i odpowiedniego HubConnectionBuilder
typu. Biorąc pod uwagę trasę koncentratora (lub System.Uri), możesz utworzyć element HubConnection
. Konstruktor może również określić dodatkowe opcje konfiguracji, w tym rejestrowanie, żądany protokół, przekazywanie tokenów uwierzytelniania i automatyczne ponowne łączenie, między innymi.
Interfejs HubConnection
API uwidacznia funkcje uruchamiania i zatrzymywania, których używasz do uruchamiania i zatrzymywania połączenia z serwerem. Ponadto istnieją możliwości przesyłania strumieniowego, wywoływania metod centrum i subskrybowania zdarzeń.
Przykładowe HubConnection
tworzenie
Aby utworzyć HubConnection
obiekt na podstawie zestawu SDK klienta platformy .NET SignalR, należy użyć HubConnectionBuilder
typu:
using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Threading.Tasks;
using RealTime.Models;
namespace ExampleClient;
public sealed class Consumer : IAsyncDisposable
{
private readonly string HostDomain =
Environment.GetEnvironmentVariable("HOST_DOMAIN");
private HubConnection _hubConnection;
public Consumer()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(new Uri($"{HostDomain}/hub/notifications"))
.WithAutomaticReconnect()
.Build();
}
public Task StartNotificationConnectionAsync() =>
_hubConnection.StartAsync();
public async ValueTask DisposeAsync()
{
if (_hubConnection is not null)
{
await _hubConnection.DisposeAsync();
_hubConnection = null;
}
}
}
Metody centrum wywołań
Jeśli klient otrzymuje wystąpienie klienta HubConnection
, które zostało pomyślnie uruchomione, klient może wywoływać metody w centrum przy użyciu InvokeAsync rozszerzeń lub SendAsync . Jeśli metoda piasty zwraca Task<TResult>
wartość , wynikiem parametru InvokeAsync<TResult>
jest typ TResult
. Jeśli metoda piasty zwróci Task
wartość , nie ma żadnego wyniku. Zarówno, InvokeAsync
jak i SendAsync
wymagają nazwy metody centrum, a zero do 10 parametrów.
- InvokeAsync: Wywołuje metodę centrum na serwerze przy użyciu określonej nazwy metody i opcjonalnych argumentów.
- SendAsync: Wywołuje metodę centrum na serwerze przy użyciu określonej nazwy metody i opcjonalnych argumentów. Ta metoda nie czeka na odpowiedź z odbiornika.
Przykład wywołania metody koncentratora
Gdy SendNotificationAsync
dodaje metodę do poprzedniej Consumer
klasy, SendNotificationAsync
deleguje do _hubConnection
metody i wywołuje NotifyAll
metodę w centrum serwera, w zależności od Notification
wystąpienia.
public Task SendNotificationAsync(string text) =>
_hubConnection.InvokeAsync(
"NotifyAll", new Notification(text, DateTime.UtcNow));
Obsługa zdarzeń
Aby obsłużyć zdarzenia, należy zarejestrować program obsługi w wystąpieniu HubConnection
. Wywołaj jedno z HubConnectionExtensions.On przeciążeń, gdy znasz nazwę metody centrum i ma zero do ośmiu parametrów. Procedura obsługi może spełniać dowolne z następujących Action
odmian:
- Action
- Action<T>
- Action<T1,T2>
- Action<T1,T2,T3>
- Action<T1,T2,T3,T4>
- Action<T1,T2,T3,T4,T5>
- Action<T1,T2,T3,T4,T5,T6>
- Action<T1,T2,T3,T4,T5,T6,T7>
- Action<T1,T2,T3,T4,T5,T6,T7,T8>
Alternatywnie możesz użyć asynchronicznych interfejsów API programu obsługi, które są Func<TResult>
miejscem, w którym TResult
jest odmiana Task
:
Func<Task>
Func<T,Task>
Func<T1,T2,Task>
Func<T1,T2,T3,Task>
Func<T1,T2,T3,T4,Task>
Func<T1,T2,T3,T4,T5,Task>
Func<T1,T2,T3,T4,T5,T6,Task>
Func<T1,T2,T3,T4,T5,T6,T7,Task>
Func<T1,T2,T3,T4,T5,T6,T7,T8,Task>
Wynikiem zarejestrowania programu obsługi zdarzeń jest IDisposable
element , który służy jako subskrypcja. Aby anulować subskrypcję programu obsługi, wywołaj metodę Dispose.
Przykładowa rejestracja zdarzeń
Aktualizując poprzednią Consumer
klasę, należy zarejestrować się w zdarzeniu, podając program obsługi i wywołując polecenie On
:
using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Threading.Tasks;
using RealTime.Models;
namespace ExampleClient;
public sealed class Consumer : IAsyncDisposable
{
private readonly string HostDomain =
Environment.GetEnvironmentVariable("HOST_DOMAIN");
private HubConnection _hubConnection;
public Consumer()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(new Uri($"{HostDomain}/hub/notifications"))
.WithAutomaticReconnect()
.Build();
_hubConnection.On<Notification>(
"NotificationReceived", OnNotificationReceivedAsync);
}
private async Task OnNotificationReceivedAsync(Notification notification)
{
// Do something meaningful with the notification.
await Task.CompletedTask;
}
// Omitted for brevity.
}
Metoda OnNotificationReceivedAsync
jest wywoływana, gdy wystąpienie centrum serwera uruchamia "NotificationReceived"
zdarzenie.
Aktualizacje zamówień na żywo firmy Contoso Pizza
Kod serwera dla aplikacji internetowej musi mieć implementację Hub
i uwidocznić trasę dla klientów. Obiekt Hub
może użyć unikatowego identyfikatora obiektu order, aby utworzyć grupę do śledzenia. Wszystkie aktualizacje zmiany stanu zamówienia mogą być następnie przekazywane w tej grupie.
Kod klienta musi również zostać zaktualizowany, aby wskazać, że aplikacja Contoso Pizza jest aplikacją zestawu WebAssembly platformy Blazor. Można użyć zestawu SDK języka JavaScript lub zestawu SDK klienta platformy .NET. Funkcję sondowania po stronie klienta można zastąpić kodem tworzącym HubConnection
element , a następnie uruchomić połączenie z serwerem. Podczas przechodzenia do strony śledzenia zamówień kod musiałby dołączyć do określonej grupy zamówienia, w której są wysyłane aktualizacje zmian. Zasubskrybujesz zdarzenie pod kątem zmian stanu zamówienia, a następnie odpowiednio go obsłużysz.