Używanie platformy ASP.NET Core SignalR z Blazor

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ten samouczek zawiera podstawowe środowisko robocze do tworzenia aplikacji w czasie rzeczywistym przy użyciu programu SignalRBlazor. Ten artykuł jest przydatny dla deweloperów, którzy są już zaznajomieni i SignalR chcą zrozumieć, jak używać SignalR w Blazor aplikacji. Aby uzyskać szczegółowe wskazówki dotyczące platform SignalR i Blazor , zobacz następujące zestawy dokumentacji referencyjnej i dokumentację interfejsu API:

Instrukcje:

  • Tworzenie Blazor aplikacji
  • Dodawanie biblioteki SignalR klienta
  • SignalR Dodawanie koncentratora
  • Dodawanie SignalR usług i punktu końcowego SignalR dla centrum
  • Razor Dodawanie kodu składnika na potrzeby czatu

Na końcu tego samouczka będziesz mieć działającą aplikację do czatu.

Wymagania wstępne

Program Visual Studio 2022 lub nowszy z pakietem roboczym ASP.NET i tworzeniem aplikacji internetowych

Przykładowa aplikacja

Pobranie przykładowej aplikacji do czatu z samouczka nie jest wymagane w tym samouczku. Przykładowa aplikacja to ostateczna, działająca aplikacja utworzona przez wykonanie kroków tego samouczka.

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Tworzenie Blazor aplikacji internetowej

Postępuj zgodnie ze wskazówkami dotyczącymi wyboru narzędzi:

Uwaga

Wymagany jest program Visual Studio 2022 lub nowszy oraz zestaw .NET Core SDK 8.0.0 lub nowszy.

Tworzenie nowego projektu.

Blazor Wybierz szablon Aplikacja internetowa. Wybierz Dalej.

Wpisz BlazorSignalRApp w polu Nazwa projektu. Upewnij się, że wpis Lokalizacja jest poprawny lub podaj lokalizację projektu. Wybierz Dalej.

Upewnij się, że platforma .NET 8 lub nowsza. Wybierz pozycję Utwórz.

Dodawanie biblioteki SignalR klienta

W Eksplorator rozwiązań kliknij prawym przyciskiem myszy BlazorSignalRApp projekt i wybierz polecenie Zarządzaj pakietami NuGet.

W oknie dialogowym Zarządzanie pakietami NuGet upewnij się, że źródło pakietu ma wartość nuget.org.

Po wybraniu pozycji Przeglądaj wpisz Microsoft.AspNetCore.SignalR.Client w polu wyszukiwania.

W wynikach wyszukiwania wybierz najnowszą wersję Microsoft.AspNetCore.SignalR.Client pakietu. Wybierz Zainstaluj.

Jeśli zostanie wyświetlone okno dialogowe Podgląd zmian, wybierz przycisk OK.

Jeśli zostanie wyświetlone okno dialogowe Akceptacja licencji, wybierz pozycję Akceptuję, jeśli zgadzasz się z postanowieniami licencyjnymi.

SignalR Dodawanie koncentratora

Utwórz folder (mnogi) i dodaj następującą ChatHub klasę Hubs (Hubs/ChatHub.cs) do katalogu głównego aplikacji:

using Microsoft.AspNetCore.SignalR;

namespace BlazorSignalRApp.Hubs;

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

Dodawanie usług i punktu końcowego SignalR dla centrum

Otwórz plik Program.

Dodaj przestrzenie nazw i Microsoft.AspNetCore.ResponseCompression klasę ChatHub na początku pliku:

using Microsoft.AspNetCore.ResponseCompression;
using BlazorSignalRApp.Hubs;

Dodaj usługi oprogramowania pośredniczącego kompresji odpowiedzi:

builder.Services.AddResponseCompression(opts =>
{
   opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[] { "application/octet-stream" });
});

Użyj oprogramowania pośredniczącego kompresji odpowiedzi w górnej części konfiguracji potoku przetwarzania:

app.UseResponseCompression();

Dodaj punkt końcowy centrum bezpośrednio po wierszu mapujący Razor składniki (app.MapRazorComponents<T>()):

app.MapHub<ChatHub>("/chathub");

Dodawanie Razor kodu składnika na potrzeby czatu

Otwórz plik Components/Pages/Home.razor.

Zastąp znacznik następującym kodem:

@page "/"
@rendermode InteractiveServer
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Home</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            InvokeAsync(StateHasChanged);
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
        {
            await hubConnection.SendAsync("SendMessage", userInput, messageInput);
        }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}

Uwaga

Wyłącz oprogramowanie pośredniczące kompresji odpowiedzi w Development środowisku podczas korzystania z Przeładowywanie na gorąco. Aby uzyskać więcej informacji, zobacz wskazówki dotyczące platformy ASP.NET CoreBlazorSignalR.

Uruchom aplikację

Postępuj zgodnie ze wskazówkami dotyczącymi narzędzi:

Naciśnij klawisz F5, aby uruchomić aplikację przy użyciu debugowania lub Ctrl+F5 (Windows)/⌘+F5 (macOS), aby uruchomić aplikację bez debugowania.

Skopiuj adres URL z paska adresu, otwórz inne wystąpienie przeglądarki lub kartę i wklej adres URL na pasku adresu.

Wybierz jedną z przeglądarek, wprowadź nazwę i komunikat, a następnie wybierz przycisk, aby wysłać wiadomość. Nazwa i komunikat są wyświetlane na obu stronach natychmiast:

SignalRBlazor Przykładowa aplikacja otwarta w dwóch oknach przeglądarki przedstawiających wymieniane komunikaty.

Cytaty: Star Trek VI: Nieodkryty kraj ©1991 Paramount

Środowisko hostowane Blazor WebAssembly

Tworzenie aplikacji

Postępuj zgodnie ze wskazówkami dotyczącymi wyboru narzędzi, aby utworzyć hostowaną Blazor WebAssembly aplikację:

Uwaga

Wymagany jest program Visual Studio 2022 lub nowszy oraz zestaw .NET Core SDK 6.0.0 lub nowszy.

Tworzenie nowego projektu.

Blazor WebAssembly Wybierz szablon Aplikacja. Wybierz Dalej.

Wpisz BlazorWebAssemblySignalRApp w polu Nazwa projektu. Upewnij się, że wpis Lokalizacja jest poprawny lub podaj lokalizację projektu. Wybierz Dalej.

W oknie dialogowym Dodatkowe informacje zaznacz pole wyboru ASP.NET Core Hosted.

Wybierz pozycję Utwórz.

Upewnij się, że utworzono hostowaną Blazor WebAssembly aplikację: w Eksplorator rozwiązań potwierdź obecność Client projektu i Server projektu. Jeśli dwa projekty nie są obecne, przed wybraniem pozycji Utwórz rozpocznij od nowa i potwierdź zaznaczenie pola wyboru ASP.NET Core Hosted.

Dodawanie biblioteki SignalR klienta

W Eksplorator rozwiązań kliknij prawym przyciskiem myszy BlazorWebAssemblySignalRApp.Client projekt i wybierz polecenie Zarządzaj pakietami NuGet.

W oknie dialogowym Zarządzanie pakietami NuGet upewnij się, że źródło pakietu ma wartość nuget.org.

Po wybraniu pozycji Przeglądaj wpisz Microsoft.AspNetCore.SignalR.Client w polu wyszukiwania.

W wynikach wyszukiwania wybierz Microsoft.AspNetCore.SignalR.Client pakiet. Ustaw wersję tak, aby odpowiadała współużytkowanej strukturze aplikacji. Wybierz Zainstaluj.

Jeśli zostanie wyświetlone okno dialogowe Podgląd zmian, wybierz przycisk OK.

Jeśli zostanie wyświetlone okno dialogowe Akceptacja licencji, wybierz pozycję Akceptuję, jeśli zgadzasz się z postanowieniami licencyjnymi.

SignalR Dodawanie koncentratora

W projekcie BlazorWebAssemblySignalRApp.Server utwórz folder (mnoga) i dodaj następującą ChatHub klasę Hubs (Hubs/ChatHub.cs):

using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

Dodawanie usług i punktu końcowego SignalR dla centrum

W projekcie BlazorWebAssemblySignalRApp.Server otwórz Program.cs plik.

Dodaj przestrzeń nazw klasy ChatHub na początku pliku:

using BlazorWebAssemblySignalRApp.Server.Hubs;

Dodaj SignalR i usługi oprogramowania pośredniczącego kompresji odpowiedzi:

builder.Services.AddSignalR();
builder.Services.AddResponseCompression(opts =>
{
      opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[] { "application/octet-stream" });
});

Użyj oprogramowania pośredniczącego kompresji odpowiedzi w górnej części konfiguracji potoku przetwarzania natychmiast po wierszu, który kompiluje aplikację:

app.UseResponseCompression();

Między punktami końcowymi kontrolerów i rezerwowym po stronie klienta dodaj punkt końcowy dla centrum. Natychmiast po wierszu app.MapControllers();dodaj następujący wiersz:

app.MapHub<ChatHub>("/chathub");

W projekcie BlazorWebAssemblySignalRApp.Server otwórz Startup.cs plik.

Dodaj przestrzeń nazw klasy ChatHub na początku pliku:

using BlazorWebAssemblySignalRApp.Server.Hubs;

Dodaj SignalR i usługi oprogramowania pośredniczącego kompresji odpowiedzi:

services.AddSignalR();
services.AddResponseCompression(opts =>
{
      opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[] { "application/octet-stream" });
});

Użyj oprogramowania pośredniczącego kompresji odpowiedzi w górnej części konfiguracji potoku przetwarzania:

app.UseResponseCompression();

Między punktami końcowymi kontrolerów i rezerwowym po stronie klienta dodaj punkt końcowy centrum bezpośrednio po wierszu endpoints.MapControllers();:

endpoints.MapHub<ChatHub>("/chathub");

Dodawanie Razor kodu składnika na potrzeby czatu

W projekcie BlazorWebAssemblySignalRApp.Client otwórz Pages/Index.razor plik.

Zastąp znacznik następującym kodem:

@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Index</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
            {
                await hubConnection.SendAsync("SendMessage", userInput, messageInput);
            }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Index</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
            {
                await hubConnection.SendAsync("SendMessage", userInput, messageInput);
            }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IAsyncDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    async Task Send() =>
        await hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected =>
        hubConnection.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    async Task Send() =>
        await hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected =>
        hubConnection.State == HubConnectionState.Connected;

    public void Dispose()
    {
        _ = hubConnection?.DisposeAsync();
    }
}

Uwaga

Wyłącz oprogramowanie pośredniczące kompresji odpowiedzi w Development środowisku podczas korzystania z Przeładowywanie na gorąco. Aby uzyskać więcej informacji, zobacz wskazówki dotyczące platformy ASP.NET CoreBlazorSignalR.

Uruchom aplikację

Postępuj zgodnie ze wskazówkami dotyczącymi narzędzi:

W Eksplorator rozwiązań wybierz BlazorWebAssemblySignalRApp.Server projekt. Naciśnij klawisz F5, aby uruchomić aplikację przy użyciu debugowania lub Ctrl+F5 (Windows)/⌘+F5 (macOS), aby uruchomić aplikację bez debugowania.

Ważne

Podczas wykonywania hostowanej Blazor WebAssembly aplikacji uruchom aplikację z projektu rozwiązaniaServer .

Przeglądarka Google Chrome lub Microsoft Edge musi być wybraną przeglądarką na potrzeby sesji debugowania.

Jeśli uruchomienie aplikacji nie powiedzie się w przeglądarce:

  • W konsoli platformy .NET upewnij się, że rozwiązanie jest uruchomione z projektu "Server".
  • Odśwież przeglądarkę przy użyciu przycisku załaduj ponownie przeglądarkę.

Skopiuj adres URL z paska adresu, otwórz inne wystąpienie przeglądarki lub kartę i wklej adres URL na pasku adresu.

Wybierz jedną z przeglądarek, wprowadź nazwę i komunikat, a następnie wybierz przycisk, aby wysłać wiadomość. Nazwa i komunikat są wyświetlane na obu stronach natychmiast:

SignalRBlazor Przykładowa aplikacja otwarta w dwóch oknach przeglądarki przedstawiających wymieniane komunikaty.

Cytaty: Star Trek VI: Nieodkryty kraj ©1991 Paramount

Blazor Server Doświadczenie

Tworzenie aplikacji

Postępuj zgodnie ze wskazówkami dotyczącymi wyboru narzędzi, aby utworzyć aplikację Blazor Server :

Uwaga

Wymagany jest program Visual Studio 2022 lub nowszy oraz zestaw .NET Core SDK 6.0.0 lub nowszy.

Tworzenie nowego projektu.

Blazor Server Wybierz szablon Aplikacja. Wybierz Dalej.

Wpisz BlazorServerSignalRApp w polu Nazwa projektu. Upewnij się, że wpis Lokalizacja jest poprawny lub podaj lokalizację projektu. Wybierz Dalej.

Wybierz pozycję Utwórz.

Dodawanie biblioteki SignalR klienta

W Eksplorator rozwiązań kliknij prawym przyciskiem myszy BlazorServerSignalRApp projekt i wybierz polecenie Zarządzaj pakietami NuGet.

W oknie dialogowym Zarządzanie pakietami NuGet upewnij się, że źródło pakietu ma wartość nuget.org.

Po wybraniu pozycji Przeglądaj wpisz Microsoft.AspNetCore.SignalR.Client w polu wyszukiwania.

W wynikach wyszukiwania wybierz Microsoft.AspNetCore.SignalR.Client pakiet. Ustaw wersję tak, aby odpowiadała współużytkowanej strukturze aplikacji. Wybierz Zainstaluj.

Jeśli zostanie wyświetlone okno dialogowe Podgląd zmian, wybierz przycisk OK.

Jeśli zostanie wyświetlone okno dialogowe Akceptacja licencji, wybierz pozycję Akceptuję, jeśli zgadzasz się z postanowieniami licencyjnymi.

Dodaj pakiet System.Text.Encodings.Web

Ta sekcja dotyczy tylko aplikacji dla ASP.NET Core w wersji 3.x.

Ze względu na problem z rozwiązaniem pakietu podczas korzystania z System.Text.Json wersji 5.x w aplikacji ASP.NET Core 3.x projekt wymaga odwołania do pakietu dla System.Text.Encodings.Webprogramu . Podstawowy problem został rozwiązany w wydaniu poprawki i przywrócono go do wersji ASP.NET Core 5.0. Aby uzyskać więcej informacji, zobacz System.Text.Json definiuje netcoreapp3.0 bez zależności (dotnet/runtime #45560).

Aby dodać System.Text.Encodings.Web go do projektu, postępuj zgodnie ze wskazówkami dotyczącymi wyboru narzędzi:

W Eksplorator rozwiązań kliknij prawym przyciskiem myszy BlazorServerSignalRApp projekt i wybierz polecenie Zarządzaj pakietami NuGet.

W oknie dialogowym Zarządzanie pakietami NuGet upewnij się, że źródło pakietu ma wartość nuget.org.

Po wybraniu pozycji Przeglądaj wpisz System.Text.Encodings.Web w polu wyszukiwania.

W wynikach wyszukiwania wybierz System.Text.Encodings.Web pakiet. Wybierz wersję pakietu, która pasuje do używanej platformy udostępnionej. Wybierz Zainstaluj.

Jeśli zostanie wyświetlone okno dialogowe Podgląd zmian, wybierz przycisk OK.

Jeśli zostanie wyświetlone okno dialogowe Akceptacja licencji, wybierz pozycję Akceptuję, jeśli zgadzasz się z postanowieniami licencyjnymi.

SignalR Dodawanie koncentratora

Utwórz folder (mnogi) i dodaj następującą ChatHub klasę Hubs (Hubs/ChatHub.cs):

using Microsoft.AspNetCore.SignalR;

namespace BlazorServerSignalRApp.Server.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
using Microsoft.AspNetCore.SignalR;

namespace BlazorServerSignalRApp.Server.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace BlazorServerSignalRApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace BlazorServerSignalRApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

Dodawanie usług i punktu końcowego SignalR dla centrum

Otwórz plik Program.cs.

Dodaj przestrzenie nazw i Microsoft.AspNetCore.ResponseCompression klasę ChatHub na początku pliku:

using Microsoft.AspNetCore.ResponseCompression;
using BlazorServerSignalRApp.Server.Hubs;

Dodaj usługi oprogramowania pośredniczącego kompresji odpowiedzi:

builder.Services.AddResponseCompression(opts =>
{
   opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[] { "application/octet-stream" });
});

Użyj oprogramowania pośredniczącego kompresji odpowiedzi w górnej części konfiguracji potoku przetwarzania:

app.UseResponseCompression();

Między punktami końcowymi mapowania Blazor koncentratora i rezerwowego po stronie klienta dodaj punkt końcowy centrum bezpośrednio po wierszu app.MapBlazorHub();:

app.MapHub<ChatHub>("/chathub");

Otwórz plik Startup.cs.

Dodaj przestrzenie nazw i Microsoft.AspNetCore.ResponseCompression klasę ChatHub na początku pliku:

using Microsoft.AspNetCore.ResponseCompression;
using BlazorServerSignalRApp.Server.Hubs;

Dodaj usługi oprogramowania pośredniczącego kompresji odpowiedzi:

services.AddResponseCompression(opts =>
{
   opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[] { "application/octet-stream" });
});

Użyj oprogramowania pośredniczącego kompresji odpowiedzi w górnej części konfiguracji potoku przetwarzania:

app.UseResponseCompression();

Między punktami końcowymi mapowania Blazor koncentratora i rezerwowego po stronie klienta dodaj punkt końcowy centrum bezpośrednio po wierszu endpoints.MapBlazorHub();:

endpoints.MapHub<ChatHub>("/chathub");

Dodawanie Razor kodu składnika na potrzeby czatu

Otwórz plik Pages/Index.razor.

Zastąp znacznik następującym kodem:

@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Index</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            InvokeAsync(StateHasChanged);
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
            {
                await hubConnection.SendAsync("SendMessage", userInput, messageInput);
            }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Index</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            InvokeAsync(StateHasChanged);
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
            {
                await hubConnection.SendAsync("SendMessage", userInput, messageInput);
            }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IAsyncDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            InvokeAsync(StateHasChanged);
        });

        await hubConnection.StartAsync();
    }

    async Task Send() =>
        await hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected =>
        hubConnection.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IAsyncDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            InvokeAsync(StateHasChanged);
        });

        await hubConnection.StartAsync();
    }

    async Task Send() =>
        await hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected =>
        hubConnection.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        await hubConnection?.DisposeAsync();
    }
}

Uwaga

Wyłącz oprogramowanie pośredniczące kompresji odpowiedzi w Development środowisku podczas korzystania z Przeładowywanie na gorąco. Aby uzyskać więcej informacji, zobacz wskazówki dotyczące platformy ASP.NET CoreBlazorSignalR.

Uruchom aplikację

Postępuj zgodnie ze wskazówkami dotyczącymi narzędzi:

Naciśnij klawisz F5, aby uruchomić aplikację przy użyciu debugowania lub Ctrl+F5 (Windows)/⌘+F5 (macOS), aby uruchomić aplikację bez debugowania.

Skopiuj adres URL z paska adresu, otwórz inne wystąpienie przeglądarki lub kartę i wklej adres URL na pasku adresu.

Wybierz jedną z przeglądarek, wprowadź nazwę i komunikat, a następnie wybierz przycisk, aby wysłać wiadomość. Nazwa i komunikat są wyświetlane na obu stronach natychmiast:

SignalRBlazor Przykładowa aplikacja otwarta w dwóch oknach przeglądarki przedstawiających wymieniane komunikaty.

Cytaty: Star Trek VI: Nieodkryty kraj ©1991 Paramount

Następne kroki

W tym samouczku zawarto informacje na temat wykonywania następujących czynności:

  • Tworzenie Blazor aplikacji
  • Dodawanie biblioteki SignalR klienta
  • SignalR Dodawanie koncentratora
  • Dodawanie SignalR usług i punktu końcowego SignalR dla centrum
  • Razor Dodawanie kodu składnika na potrzeby czatu

Aby uzyskać szczegółowe wskazówki dotyczące platform SignalR i Blazor , zobacz następujące zestawy dokumentacji referencyjnej:

Dodatkowe zasoby