Tutorial: Erste Schritte mit ASP.NET Core SignalR

In diesem Tutorial werden die Grundlagen zur Erstellung einer Echtzeit-App mit SignalR beschrieben. Sie lernen Folgendes:

  • Erstellen Sie ein Webprojekt.
  • Fügen Sie die SignalR-Clientbibliothek hinzu.
  • Erstellen Sie einen SignalR-Hub.
  • Konfigurieren Sie das Projekt für die Verwendung von SignalR.
  • Hinzufügen von Code, mit dem Nachrichten von jedem Client an alle verbundene Clients gesendet werden.

Am Ende verfügen Sie über eine funktionierende Chat-App:

SignalR sample app

Voraussetzungen

Erstellen Sie ein Web-App-Projekt.

  1. Starten Sie Visual Studio 2022, und wählen Sie Neues Projekt erstellen aus.

    Create a new project from the start window

  2. Wählen Sie im Dialogfeld Neues Projekt erstellen die Option ASP.NET Core-Web-App aus, und klicken Sie dann auf Weiter.

    Create an ASP.NET Core Web App

  3. Geben Sie SignalRChat im Dialogfeld Neues Projekt konfigurieren für Projektname ein. Es ist wichtig, dem Projekt den Namen SignalRChat in übereinstimmender Groß-/Kleinschreibung zu geben, damit die Namespaces übereinstimmen, wenn Sie Beispielcode kopieren und einfügen.

  4. Wählen Sie Weiter aus.

  5. Wählen Sie im Dialogfeld Zusätzliche Informationen die Option .NET 6.0 (Langfristiger Support) und dann Erstellen aus.

    Additional information

Hinzufügen der SignalR-Clientbibliothek

Die SignalR-Serverbibliothek ist im freigegebenen ASP.NET Core-Framework enthalten. Die JavaScript-Clientbibliothek ist nicht automatisch im Projekt enthalten. In diesem Tutorial verwenden Sie den Bibliotheks-Manager (LibMan), um die Clientbibliothek aus unpkg abzurufen. unpkgist ein schnelles, globales Inhaltsbereitstellungsnetzwerk für alles in npm.

  • Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Hinzufügen>Client-Side Library (Clientseitige Bibliothek) aus.
  • Gehen Sie im Dialogfeld Clientseitige Bibliothek hinzufügen so vor:
    • Wählen Sie unpkg als Anbieter aus.
    • Geben Sie @microsoft/signalr@latest für Bibliothek ein.
    • Klicken Sie auf Choose specific files (Spezifische Dateien auswählen), erweitern Sie den Ordner dist/browser, und wählen Sie signalr.js und signalr.min.js aus.
    • Legen Sie wwwroot/js/signalr/ als Zielspeicherort fest.
    • Wählen Sie Installieren aus.

Add Client-Side Library dialog - select library

Der Ordner wwwroot/js/signalr wird von LibMan erstellt, und die ausgewählten Dateien werden in ihn hineinkopiert.

Erstellen eines SignalR-Hubs

Ein Hub ist eine Klasse, die als grundlegende Pipeline verwendet wird, mit der Client/Server-Kommunikation verarbeitet wird.

  • Erstellen Sie im SignalRChat-Projektordner einen Hubs-Ordner.
  • Erstellen Sie mit dem folgenden Code im Ordner Hubs die ChatHub-Klasse:
using Microsoft.AspNetCore.SignalR;

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

Die ChatHub-Klasse erbt von der Hub-Klasse von SignalR. Die Hub-Klasse verwaltet Verbindungen, Gruppen und Messaging.

Die SendMessage-Methode kann von einem verbundenen Client aufgerufen werden, um eine Nachricht an alle Clients zu senden. JavaScript-Clientcode, in dem die Methode aufgerufen wird, wird später in diesem Tutorial vorgestellt. SignalR-Code ist asynchron, damit die maximale Skalierbarkeit gewährleistet werden kann.

Konfigurieren von SignalR

Der SignalR-Server muss so konfiguriert werden, dass er SignalR-Anforderungen an SignalR weiterleitet. Fügen Sie der Datei Program.cs den folgenden hervorgehobenen Code zu.

using SignalRChat.Hubs;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();
app.MapHub<ChatHub>("/chatHub");

app.Run();

Der hervorgehobene Code fügt den Abhängigkeitsinjektions- und Routingsystemen von ASP.NET Core SignalR hinzu.

Hinzufügen von SignalR-Clientcode

  • Ersetzen Sie den Inhalt in Pages/Index.cshtml durch den folgenden Code:

    @page
        <div class="container">
            <div class="row">&nbsp;</div>
            <div class="row">
                <div class="col-2">User</div>
                <div class="col-4"><input type="text" id="userInput" /></div>
            </div>
            <div class="row">
                <div class="col-2">Message</div>
                <div class="col-4"><input type="text" id="messageInput" /></div>
            </div>
            <div class="row">&nbsp;</div>
            <div class="row">
                <div class="col-6">
                    <input type="button" id="sendButton" value="Send Message" />
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-12">
                <hr />
            </div>
        </div>
        <div class="row">
            <div class="col-6">
                <ul id="messagesList"></ul>
            </div>
        </div>
    <script src="~/js/signalr/dist/browser/signalr.js"></script>
    <script src="~/js/chat.js"></script>
    

    Das obenstehende Markup:

    • Erstellt Textfelder und eine Schaltfläche zum Übermitteln.
    • erstellt eine Liste mit id="messagesList" zum Anzeigen von Nachrichten, die vom SignalR-Hub empfangen werden
    • Enthält Skriptverweise auf SignalR, und der App-Code von chat.js wird im nächsten Schritt erstellt.
  • Erstellen Sie im wwwroot/js-Ordner eine chat.js-Datei mit folgendem Code:

    "use strict";
    
    var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
    
    //Disable the send button until connection is established.
    document.getElementById("sendButton").disabled = true;
    
    connection.on("ReceiveMessage", function (user, message) {
        var li = document.createElement("li");
        document.getElementById("messagesList").appendChild(li);
        // We can assign user-supplied strings to an element's textContent because it
        // is not interpreted as markup. If you're assigning in any other way, you 
        // should be aware of possible script injection concerns.
        li.textContent = `${user} says ${message}`;
    });
    
    connection.start().then(function () {
        document.getElementById("sendButton").disabled = false;
    }).catch(function (err) {
        return console.error(err.toString());
    });
    
    document.getElementById("sendButton").addEventListener("click", function (event) {
        var user = document.getElementById("userInput").value;
        var message = document.getElementById("messageInput").value;
        connection.invoke("SendMessage", user, message).catch(function (err) {
            return console.error(err.toString());
        });
        event.preventDefault();
    });
    

    Der vorstehende JavaScript-Code:

    • erstellt und startet eine Verbindung
    • fügt einen Handler zur Senden-Schaltfläche hinzu, der Nachrichten an den Hub sendet
    • fügt einen Handler zum Verbindungsobjekt hinzu, der Nachrichten vom Hub empfängt und diese der Liste hinzufügt

Ausführen der App

  • Drücken Sie STRG+F5, um die App ohne Debugging zu starten.
  • 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 Nachricht senden. Der Name und die Nachricht werden sofort auf beiden Seiten angezeigt.

SignalR sample app

Tipp

  • Wenn die App nicht funktioniert, öffnen Sie die Browser-Entwicklungstools (F12), und wechseln Sie zur Konsole. Möglicherweise werden Fehler in Bezug auf Ihren HTML- und JavaScript-Code angezeigt. Nehmen wir an, dass Sie z.B. signalr.js in einen anderen Ordner als vorgeschrieben platziert haben. In diesem Fall funktioniert der Verweis auf diese Datei nicht, und Ihnen wird der Fehler 404 in der Konsole angezeigt. signalr.js not found error

  • Wenn Sie den Fehler ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY in Chrome erhalten, führen Sie folgende Befehle aus, um das Entwicklungszertifikat zu aktualisieren:

    dotnet dev-certs https --clean
    dotnet dev-certs https --trust
    

Veröffentlichen in Azure

Weitere Informationen zur Bereistellung in Azure finden Sie unter Schnellstart: Bereitstellen einer ASP.NET-Web-App.

In diesem Tutorial werden die Grundlagen zur Erstellung einer Echtzeit-App mit SignalR beschrieben. Sie lernen Folgendes:

  • Erstellen Sie ein Webprojekt.
  • Fügen Sie die SignalR-Clientbibliothek hinzu.
  • Erstellen Sie einen SignalR-Hub.
  • Konfigurieren Sie das Projekt für die Verwendung von SignalR.
  • Hinzufügen von Code, mit dem Nachrichten von jedem Client an alle verbundene Clients gesendet werden.

Am Ende verfügen Sie über eine funktionierende Chat-App:

SignalR sample app

Voraussetzungen

Erstellen Sie ein Web-App-Projekt.

  • Klicken Sie im Menü auf Datei > Neues Projekt.
  • Wählen Sie im Dialogfeld Neues Projekt erstellen die Option ASP.NET Core-Webanwendung aus, und klicken Sie dann auf Weiter.
  • Geben Sie im Dialogfeld Neues Projekt konfigurieren dem Projekt den Namen SignalRChat, und wählen Sie dann Erstellen aus.
  • Wählen Sie im Dialogfeld Neue ASP.NET Core-Webanwendung erstellen die Optionen .NET Core und ASP.NET Core 3.1 aus.
  • Klicken Sie auf Webanwendung, um ein Projekt zu erstellen, das Razor Pages verwendet, und wählen Sie dann Erstellen aus.

New Project dialog in Visual Studio

Hinzufügen der SignalR-Clientbibliothek

Die SignalR-Serverbibliothek ist im freigegebenen ASP.NET Core 3.1-Framework enthalten. Die JavaScript-Clientbibliothek ist nicht automatisch im Projekt enthalten. In diesem Tutorial verwenden Sie den Bibliotheks-Manager (LibMan), um die Clientbibliothek von unpkg abzurufen. unpkg ist ein CDN (Content Delivery Network), mit dem Sie alles bereitstellen können, was im npm (Node.js-Paket-Manager) zu finden ist.

  • Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Hinzufügen>Client-Side Library (Clientseitige Bibliothek) aus.
  • Wählen Sie unpkg im Dialogfeld Add Client-Side Library (Clientseitige Bibliothek hinzufügen) als Anbieter aus.
  • Geben Sie für Bibliothek@microsoft/signalr@latest ein.
  • Klicken Sie auf Choose specific files (Spezifische Dateien auswählen), erweitern Sie den Ordner dist/browser, und wählen Sie signalr.js und signalr.min.js aus.
  • Legen Sie wwwroot/js/signalr/ als Zielspeicherort fest.
  • Wählen Sie Installieren aus.

Add Client-Side Library dialog - select library

Der Ordner wwwroot/js/signalr wird von LibMan erstellt, und die ausgewählten Dateien werden in ihn hineinkopiert.

Erstellen eines SignalR-Hubs

Ein Hub ist eine Klasse, die als grundlegende Pipeline verwendet wird, mit der Client/Server-Kommunikation verarbeitet wird.

  • Erstellen Sie im SignalRChat-Projektordner einen Hubs-Ordner.
  • Erstellen Sie im Hubs-Ordner eine ChatHub.cs-Datei mit folgendem Code:
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

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

Die ChatHub-Klasse erbt von der Hub-Klasse von SignalR. Die Hub-Klasse verwaltet Verbindungen, Gruppen und Messaging.

Die SendMessage-Methode kann von einem verbundenen Client aufgerufen werden, um eine Nachricht an alle Clients zu senden. JavaScript-Clientcode, in dem die Methode aufgerufen wird, wird später in diesem Tutorial vorgestellt. SignalR-Code ist asynchron, damit die maximale Skalierbarkeit gewährleistet werden kann.

Konfigurieren von SignalR

Der SignalR-Server muss so konfiguriert werden, dass er SignalR-Anforderungen an SignalR weiterleitet.

  • Fügen Sie der Datei Startup.cs den folgenden hervorgehobenen Code zu.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.HttpsPolicy;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using SignalRChat.Hubs;
    
    namespace SignalRChat
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddRazorPages();
                services.AddSignalR();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Error");
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
    
                app.UseHttpsRedirection();
                app.UseStaticFiles();
    
                app.UseRouting();
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapRazorPages();
                    endpoints.MapHub<ChatHub>("/chatHub");
                });
            }
        }
    }
    

    Durch diese Änderungen wird der ASP.NET Core-Abhängigkeitsinjektion und den Routingsystemen SignalR hinzugefügt.

Hinzufügen von SignalR-Clientcode

  • Ersetzen Sie den Inhalt in Pages/Index.cshtml durch den folgenden Code:

    @page
        <div class="container">
            <div class="row">&nbsp;</div>
            <div class="row">
                <div class="col-2">User</div>
                <div class="col-4"><input type="text" id="userInput" /></div>
            </div>
            <div class="row">
                <div class="col-2">Message</div>
                <div class="col-4"><input type="text" id="messageInput" /></div>
            </div>
            <div class="row">&nbsp;</div>
            <div class="row">
                <div class="col-6">
                    <input type="button" id="sendButton" value="Send Message" />
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-12">
                <hr />
            </div>
        </div>
        <div class="row">
            <div class="col-6">
                <ul id="messagesList"></ul>
            </div>
        </div>
    <script src="~/js/signalr/dist/browser/signalr.js"></script>
    <script src="~/js/chat.js"></script>
    

    Der vorangehende Code:

    • erstellt Textfelder für den Namen und den Nachrichtentext sowie eine Senden-Schaltfläche
    • erstellt eine Liste mit id="messagesList" zum Anzeigen von Nachrichten, die vom SignalR-Hub empfangen werden
    • schließt Skriptverweise auf SignalR sowie den chat.js-Anwendungscode ein, den Sie im folgenden Schritt erstellen
  • Erstellen Sie im wwwroot/js-Ordner eine chat.js-Datei mit folgendem Code:

    "use strict";
    
    var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
    
    //Disable send button until connection is established
    document.getElementById("sendButton").disabled = true;
    
    connection.on("ReceiveMessage", function (user, message) {
        var li = document.createElement("li");
        document.getElementById("messagesList").appendChild(li);
        // We can assign user-supplied strings to an element's textContent because it
        // is not interpreted as markup. If you're assigning in any other way, you 
        // should be aware of possible script injection concerns.
        li.textContent = `${user} says ${message}`;
    });
    
    connection.start().then(function () {
        document.getElementById("sendButton").disabled = false;
    }).catch(function (err) {
        return console.error(err.toString());
    });
    
    document.getElementById("sendButton").addEventListener("click", function (event) {
        var user = document.getElementById("userInput").value;
        var message = document.getElementById("messageInput").value;
        connection.invoke("SendMessage", user, message).catch(function (err) {
            return console.error(err.toString());
        });
        event.preventDefault();
    });
    

    Der vorangehende Code:

    • erstellt und startet eine Verbindung
    • fügt einen Handler zur Senden-Schaltfläche hinzu, der Nachrichten an den Hub sendet
    • fügt einen Handler zum Verbindungsobjekt hinzu, der Nachrichten vom Hub empfängt und diese der Liste hinzufügt

Ausführen der App

  • Drücken Sie STRG+F5, um die App ohne Debugging zu starten.
  • 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 Nachricht senden. Der Name und die Nachricht werden sofort auf beiden Seiten angezeigt.

SignalR sample app

Tipp

  • Wenn die App nicht funktioniert, öffnen Sie die Browser-Entwicklungstools (F12), und wechseln Sie zur Konsole. Möglicherweise werden Fehler in Bezug auf Ihren HTML- und JavaScript-Code angezeigt. Nehmen wir an, dass Sie z.B. signalr.js in einen anderen Ordner als vorgeschrieben platziert haben. In diesem Fall funktioniert der Verweis auf diese Datei nicht, und Ihnen wird der Fehler 404 in der Konsole angezeigt. signalr.js not found error

  • Wenn Sie den Fehler ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY in Chrome erhalten, führen Sie folgende Befehle aus, um das Entwicklungszertifikat zu aktualisieren:

    dotnet dev-certs https --clean
    dotnet dev-certs https --trust
    

Veröffentlichen in Azure

Weitere Informationen zur Bereistellung in Azure finden Sie unter Schnellstart: Bereitstellen einer ASP.NET-Web-App.