Verwenden von ASP.NET Core SignalR mit Blazor

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Dieses Tutorial bietet eine grundlegende Arbeitserfahrung zum Erstellen einer Echtzeit-App unter Verwendung von SignalR mit Blazor. Dieser Artikel ist nützlich für Entwickler, die bereits mit SignalR vertraut sind und versuchen, zu verstehen, wie SignalR in einer Blazor-App angewendet wird. Ausführliche Anleitungen zu den SignalR- und Blazor-Frameworks finden Sie in den folgenden Referenzdokumentationssätzen und in der API-Dokumentation:

In diesem Artikel werden folgende Themen erläutert:

  • Erstellen einer Blazor-App
  • Hinzufügen der SignalR-Clientbibliothek
  • Hinzufügen eines SignalR-Hubs
  • Hinzufügen von SignalR-Diensten und eines Endpunkts zum SignalR-Hub
  • Hinzufügen eines Razor-Komponentencodes für Chat

Am Ende dieses Tutorials verfügen Sie über eine funktionierende Chat-App.

Voraussetzungen

Visual Studio 2022 oder höher mit der Workload ASP.NET und Webentwicklung

Beispiel-App

Das Herunterladen des Beispiels einer Chat-App im Tutorial ist für dieses Tutorial nicht erforderlich. Die Beispiel-App ist die letzte funktionierende App, die mithilfe der Schritte dieses Tutorials erstellt wurde.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Erstellen einer „Blazor“-Web-App

Befolgen Sie die Anleitungen für die Auswahl der Tools:

Hinweis

Visual Studio 2022 oder höher und das .NET Core SDK 8.0.0 oder höher sind erforderlich.

Erstelle ein neues Projekt.

Wählen Sie die “Blazor“-Web-App-Vorlage aus. Klicken Sie auf Weiter.

Geben Sie im Feld ProjektnameBlazorSignalRApp ein. Vergewissern Sie sich, dass der Eintrag für den Speicherort korrekt ist, oder geben Sie einen Speicherort für das Projekt an. Wählen Sie Weiter aus.

Vergewissern Sie sich, dass es sich beim Framework um .NET 8 oder höher handelt. Wählen Sie Erstellen aus.

Hinzufügen der SignalR-Clientbibliothek

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das BlazorSignalRApp-Projekt, und wählen Sie NuGet-Pakete verwalten aus.

Überprüfen Sie im Dialogfeld NuGet-Pakete verwalten, ob die Paketquelle auf nuget.org eingestellt ist.

Geben Sie bei Auswahl von DurchsuchenMicrosoft.AspNetCore.SignalR.Client in das Suchfeld ein.

Wählen Sie in den Suchergebnissen die neueste Version des Microsoft.AspNetCore.SignalR.Client-Pakets aus. Wählen Sie Installieren aus.

Wenn das Dialogfeld Vorschau der Änderungen anzeigen angezeigt wird, wählen Sie die Option OK aus.

Wenn das Dialogfeld Zustimmung zur Lizenz erscheint, wählen Sie Ich stimme zu aus, wenn Sie mit den Lizenzbedingungen einverstanden sind.

Hinzufügen eines SignalR-Hubs

Erstellen Sie einen Hubs (Plural)-Ordner, und fügen Sie die folgende ChatHub-Klasse (Hubs/ChatHub.cs) zum Stamm der App hinzu:

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);
    }
}

Hinzufügen von Diensten und eines Endpunkts zum SignalR-Hub

Öffnen Sie die Datei Program .

Fügen Sie am Anfang der Datei die Namespaces für Microsoft.AspNetCore.ResponseCompression und die ChatHub-Klasse hinzu:

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

Fügen Sie Middlewaredienste für die Komprimierung von Antworten hinzu:

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

Verwenden Sie die Middlewaredienste für die Komprimierung von Antworten am Anfang der Konfiguration der Verarbeitungspipeline:

app.UseResponseCompression();

Fügen Sie einen Endpunkt für den Hub unmittelbar nach der Zeile hinzu, die Razor-Komponenten (app.MapRazorComponents<T>()) zuordnet:

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

Hinzufügen von Razor-Komponentencode für Chat

Öffnen Sie die Datei Components/Pages/Home.razor .

Ersetzen Sie das Markup durch folgenden Code:

@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();
        }
    }
}

Hinweis

Deaktivieren Sie die Middlewaredienste für die Komprimierung von Antworten in der Development-Umgebung, wenn Sie Hot Reload verwenden. Weitere Informationen finden Sie in den Anleitungen zu ASP.NET Core BlazorSignalR.

Ausführen der App

Befolgen Sie die Anleitungen für die Auswahl Ihrer Tools:

Drücken Sie F5, um die App mit Debuggen auszuführen, oder drücken Sie STRG+F5 (Windows)/+F5 (macOS), um die App ohne Debuggen auszuführen.

Kopieren Sie die URL aus der Adressleiste, öffnen Sie eine neue Browserinstanz oder Registerkarte, und fügen Sie die URL in die Adressleiste ein.

Geben Sie in einem der beiden Browser einen Namen und eine Nachricht ein, und klicken Sie auf die Schaltfläche zum Senden der Nachricht. Der Name und die Nachricht werden sofort auf beiden Seiten angezeigt:

SignalRBlazorDie-Beispiel-App wird in zwei Browserfenstern geöffnet, in denen die ausgetauschten Nachrichten angezeigt werden.

Zitate: Star Trek VI: The Undiscovered Country (Das unentdeckte Land) ©1991 Paramount

Gehostete Blazor WebAssembly-Oberfläche

Erstellen der App

Befolgen Sie die Anleitungen für die Auswahl der Tools zum Erstellen einer gehosteten Blazor WebAssembly-App:

Hinweis

Visual Studio 2022 oder höher und das .NET Core SDK 6.0.0 oder höher sind erforderlich.

Erstellen Sie ein neues Projekt.

Wählen Sie die Blazor WebAssembly App-Vorlage aus. Klicken Sie auf Weiter.

Geben Sie im Feld ProjektnameBlazorWebAssemblySignalRApp ein. Vergewissern Sie sich, dass der Eintrag für den Speicherort korrekt ist, oder geben Sie einen Speicherort für das Projekt an. Klicken Sie auf Weiter.

Aktivieren Sie im Dialogfeld Zusätzliche Informationen das Kontrollkästchen Von ASP.NET Core gehostet.

Wählen Sie Erstellen aus.

Vergewissern Sie sich, dass eine gehostete Blazor WebAssembly-App erstellt wurde: Im Projektmappen-Explorer bestätigen Sie, dass ein Client-Projekt und ein Server-Projekt vorhanden sind. Wenn die beiden Projekte nicht vorliegen, beginnen Sie von vorn, und stellen Sie sicher, dass das Kontrollkästchen In ASP.NET Core gehostet aktiviert ist, bevor Sie auf Erstellen klicken.

Hinzufügen der SignalR-Clientbibliothek

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das BlazorWebAssemblySignalRApp.Client-Projekt, und wählen Sie NuGet-Pakete verwalten aus.

Überprüfen Sie im Dialogfeld NuGet-Pakete verwalten, ob die Paketquelle auf nuget.org eingestellt ist.

Geben Sie bei Auswahl von DurchsuchenMicrosoft.AspNetCore.SignalR.Client in das Suchfeld ein.

Wählen Sie in den Suchergebnissen das Paket Microsoft.AspNetCore.SignalR.Client aus. Legen Sie die Version so fest, dass sie zum freigegebenen Framework der App passt. Wählen Sie Installieren aus.

Wenn das Dialogfeld Vorschau der Änderungen anzeigen angezeigt wird, wählen Sie die Option OK aus.

Wenn das Dialogfeld Zustimmung zur Lizenz erscheint, wählen Sie Ich stimme zu aus, wenn Sie mit den Lizenzbedingungen einverstanden sind.

Hinzufügen eines SignalR-Hubs

Erstellen Sie im BlazorWebAssemblySignalRApp.Server-Projekt einen Hubs-Ordner (Plural), und fügen Sie die folgende ChatHub-Klasse (Hubs/ChatHub.cs) hinzu:

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);
        }
    }
}

Hinzufügen von Diensten und eines Endpunkts zum SignalR-Hub

Öffnen Sie im Projekt BlazorWebAssemblySignalRApp.Server die Datei Program.cs.

Fügen Sie am Anfang der Datei den Namespace für die ChatHub-Klasse hinzu:

using BlazorWebAssemblySignalRApp.Server.Hubs;

Fügen Sie SignalR und Middlewaredienste für die Komprimierung von Antworten hinzu:

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

Verwenden Sie die Middleware für die Reaktionskomprimierung am Anfang der Konfiguration der Verarbeitungspipeline unmittelbar nach der Zeile, die die App erstellt:

app.UseResponseCompression();

Fügen Sie zwischen den Endpunkten für Controller und dem clientseitigen Fallback einen Endpunkt für den Hub hinzu. Fügen Sie unmittelbar nach der Zeile app.MapControllers(); folgende Zeile hinzu:

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

Öffnen Sie im Projekt BlazorWebAssemblySignalRApp.Server die Datei Startup.cs.

Fügen Sie am Anfang der Datei den Namespace für die ChatHub-Klasse hinzu:

using BlazorWebAssemblySignalRApp.Server.Hubs;

Fügen Sie SignalR und Middlewaredienste für die Komprimierung von Antworten hinzu:

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

Verwenden Sie die Middlewaredienste für die Komprimierung von Antworten am Anfang der Konfiguration der Verarbeitungspipeline:

app.UseResponseCompression();

Fügen Sie zwischen den Endpunkten für Controller und dem clientseitigen Fallback unmittelbar nach der Zeile endpoints.MapControllers(); einen Endpunkt für den Hub hinzu:

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

Hinzufügen von Razor-Komponentencode für Chat

Öffnen Sie im Projekt BlazorWebAssemblySignalRApp.Client die Datei Pages/Index.razor.

Ersetzen Sie das Markup durch folgenden Code:

@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();
    }
}

Hinweis

Deaktivieren Sie die Middlewaredienste für die Komprimierung von Antworten in der Development-Umgebung, wenn Sie Hot Reload verwenden. Weitere Informationen finden Sie in den Anleitungen zu ASP.NET Core BlazorSignalR.

Ausführen der App

Befolgen Sie die Anleitungen für die Auswahl Ihrer Tools:

Wählen Sie im Projektmappen-Explorer das BlazorWebAssemblySignalRApp.Server-Projekt aus. Drücken Sie F5, um die App mit Debuggen auszuführen, oder drücken Sie STRG+F5 (Windows)/+F5 (macOS), um die App ohne Debuggen auszuführen.

Wichtig

Wenn Sie eine gehostete Blazor WebAssembly App ausführen, führen Sie die App aus dem ServerProjekt der Projektmappe aus.

Google Chrome oder Microsoft Edge muss der für eine Debugsitzung ausgewählte Browser sein.

Wenn die App nicht im Browser gestartet werden kann:

  • Vergewissern Sie sich in der .NET-Konsole, dass die Lösung über das Projekt „Server“ ausgeführt wird.
  • Aktualisieren Sie den Browser mithilfe der Schaltfläche zum erneuten Laden des Browsers.

Kopieren Sie die URL aus der Adressleiste, öffnen Sie eine neue Browserinstanz oder Registerkarte, und fügen Sie die URL in die Adressleiste ein.

Geben Sie in einem der beiden Browser einen Namen und eine Nachricht ein, und klicken Sie auf die Schaltfläche zum Senden der Nachricht. Der Name und die Nachricht werden sofort auf beiden Seiten angezeigt:

SignalRBlazorDie-Beispiel-App wird in zwei Browserfenstern geöffnet, in denen die ausgetauschten Nachrichten angezeigt werden.

Zitate: Star Trek VI: The Undiscovered Country (Das unentdeckte Land) ©1991 Paramount

Blazor Server-Benutzeroberfläche

Erstellen der App

Befolgen Sie die Anleitungen für die Auswahl der Tools zum Erstellen einer Blazor Server-App:

Hinweis

Visual Studio 2022 oder höher und das .NET Core SDK 6.0.0 oder höher sind erforderlich.

Erstellen Sie ein neues Projekt.

Wählen Sie die Blazor Server-App-Vorlage aus. Klicken Sie auf Weiter.

Geben Sie im Feld ProjektnameBlazorServerSignalRApp ein. Vergewissern Sie sich, dass der Eintrag für den Speicherort korrekt ist, oder geben Sie einen Speicherort für das Projekt an. Klicken Sie auf Weiter.

Wählen Sie Erstellen aus.

Hinzufügen der SignalR-Clientbibliothek

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das BlazorServerSignalRApp-Projekt, und wählen Sie NuGet-Pakete verwalten aus.

Überprüfen Sie im Dialogfeld NuGet-Pakete verwalten, ob die Paketquelle auf nuget.org eingestellt ist.

Geben Sie bei Auswahl von DurchsuchenMicrosoft.AspNetCore.SignalR.Client in das Suchfeld ein.

Wählen Sie in den Suchergebnissen das Paket Microsoft.AspNetCore.SignalR.Client aus. Legen Sie die Version so fest, dass sie zum freigegebenen Framework der App passt. Wählen Sie Installieren aus.

Wenn das Dialogfeld Vorschau der Änderungen anzeigen angezeigt wird, wählen Sie die Option OK aus.

Wenn das Dialogfeld Zustimmung zur Lizenz erscheint, wählen Sie Ich stimme zu aus, wenn Sie mit den Lizenzbedingungen einverstanden sind.

Hinzufügen des System.Text.Encodings.Web-Pakets

Dieser Abschnitt gilt nur für Apps für ASP.NET Core Version 3.x.

Aufgrund eines Problems bei der Paketauflösung bei der Verwendung von System.Text.Json 5.x in einer ASP.NET Core 3.x-App erfordert das Projekt einen Paketverweis für System.Text.Encodings.Web. Das zugrunde liegende Problem wurde in einem Patch behoben und auf ASP.NET Core 5.0 zurück portiert. Weitere Informationen finden Sie unter System.Text.Json defines netcoreapp3.0 with no dependencies #45560 (System.Text.Json definiert netcoreapp3.0 ohne Abhängigkeiten – Nr.45560).

Befolgen Sie den Leitfaden für Ihr bevorzugtes Tool, um System.Text.Encodings.Web zum Projekt hinzuzufügen:

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das BlazorServerSignalRApp-Projekt, und wählen Sie NuGet-Pakete verwalten aus.

Überprüfen Sie im Dialogfeld NuGet-Pakete verwalten, ob die Paketquelle auf nuget.org eingestellt ist.

Geben Sie bei Auswahl von DurchsuchenSystem.Text.Encodings.Web in das Suchfeld ein.

Wählen Sie in den Suchergebnissen das Paket System.Text.Encodings.Web aus. Wählen Sie die Version des Pakets aus, die zum verwendeten freigegebenen Framework passt. Wählen Sie Installieren aus.

Wenn das Dialogfeld Vorschau der Änderungen anzeigen angezeigt wird, wählen Sie die Option OK aus.

Wenn das Dialogfeld Zustimmung zur Lizenz erscheint, wählen Sie Ich stimme zu aus, wenn Sie mit den Lizenzbedingungen einverstanden sind.

Hinzufügen eines SignalR-Hubs

Erstellen Sie einen Hubs-Ordner (Plural), und fügen Sie die folgende ChatHub-Klasse (Hubs/ChatHub.cs) hinzu:

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);
        }
    }
}

Hinzufügen von Diensten und eines Endpunkts zum SignalR-Hub

Öffnen Sie die Datei Program.cs .

Fügen Sie am Anfang der Datei die Namespaces für Microsoft.AspNetCore.ResponseCompression und die ChatHub-Klasse hinzu:

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

Fügen Sie Middlewaredienste für die Komprimierung von Antworten hinzu:

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

Verwenden Sie die Middlewaredienste für die Komprimierung von Antworten am Anfang der Konfiguration der Verarbeitungspipeline:

app.UseResponseCompression();

Fügen Sie zwischen den Endpunkten für die Zuordnung des Blazor-Hubs und dem clientseitigen Fallback unmittelbar nach der Zeile app.MapBlazorHub(); einen Endpunkt für den Hub hinzu:

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

Öffnen Sie die Datei Startup.cs .

Fügen Sie am Anfang der Datei die Namespaces für Microsoft.AspNetCore.ResponseCompression und die ChatHub-Klasse hinzu:

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

Fügen Sie Middlewaredienste für die Komprimierung von Antworten hinzu:

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

Verwenden Sie die Middlewaredienste für die Komprimierung von Antworten am Anfang der Konfiguration der Verarbeitungspipeline:

app.UseResponseCompression();

Fügen Sie zwischen den Endpunkten für die Zuordnung des Blazor-Hubs und dem clientseitigen Fallback unmittelbar nach der Zeile endpoints.MapBlazorHub(); einen Endpunkt für den Hub hinzu:

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

Hinzufügen von Razor-Komponentencode für Chat

Öffnen Sie die Datei Pages/Index.razor .

Ersetzen Sie das Markup durch folgenden Code:

@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();
    }
}

Hinweis

Deaktivieren Sie die Middlewaredienste für die Komprimierung von Antworten in der Development-Umgebung, wenn Sie Hot Reload verwenden. Weitere Informationen finden Sie in den Anleitungen zu ASP.NET Core BlazorSignalR.

Ausführen der App

Befolgen Sie die Anleitungen für die Auswahl Ihrer Tools:

Drücken Sie F5, um die App mit Debuggen auszuführen, oder drücken Sie STRG+F5 (Windows)/+F5 (macOS), um die App ohne Debuggen auszuführen.

Kopieren Sie die URL aus der Adressleiste, öffnen Sie eine neue Browserinstanz oder Registerkarte, und fügen Sie die URL in die Adressleiste ein.

Geben Sie in einem der beiden Browser einen Namen und eine Nachricht ein, und klicken Sie auf die Schaltfläche zum Senden der Nachricht. Der Name und die Nachricht werden sofort auf beiden Seiten angezeigt:

SignalRBlazorDie-Beispiel-App wird in zwei Browserfenstern geöffnet, in denen die ausgetauschten Nachrichten angezeigt werden.

Zitate: Star Trek VI: The Undiscovered Country (Das unentdeckte Land) ©1991 Paramount

Nächste Schritte

In diesem Tutorial haben Sie Folgendes gelernt:

  • Erstellen einer Blazor-App
  • Hinzufügen der SignalR-Clientbibliothek
  • Hinzufügen eines SignalR-Hubs
  • Hinzufügen von SignalR-Diensten und eines Endpunkts zum SignalR-Hub
  • Hinzufügen eines Razor-Komponentencodes für Chat

Ausführliche Anleitungen zu den SignalR- und Blazor-Frameworks finden Sie in den folgenden Referenzdokumentationssätzen:

Zusätzliche Ressourcen