Jak działa ASP.NET Core SignalR

Ukończone

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:

  • Hub: koncentrator standardowy.
  • Hub<T>: silnie typizowane centrum ogólne.

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. NotificationHubjest podklasą .Hub Metoda NotifyAll zwraca wartość Taski akceptuje pojedynczy Notification parametr. Metoda jest wyrażona jako wywołanie z SendAsyncClients.Allklasy , 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 i T 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 lub Task<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

    ASP.NET Core SignalR hub wysyłający komunikat z clients.All składni.

    Wszyscy połączeni klienci otrzymują ten komunikat niezależnie od grupy, do której mogą należeć lub nie należą.

  • Izolowany użytkownik

    ASP.NET Core SignalR hub wysyłający komunikat z składnią Clients.User.

    Jeden użytkownik otrzymuje ten komunikat niezależnie od liczby aktualnie używanych urządzeń.

  • Grupa izolowana

    ASP.NET Core SignalR hub wysyłający komunikat za pomocą składni Clients.Group.

    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 Taskwartość , 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:

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 :

Wynikiem zarejestrowania programu obsługi zdarzeń jest IDisposableelement , 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 HubConnectionelement , 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.