Schnellstart: Erstellen eines Chatraums mit SignalR Service

Azure SignalR Service ist ein Azure-Dienst, der Entwicklern die einfache Erstellung von Webanwendungen mit Echtzeitfunktionen ermöglicht.

In diesem Artikel wird der Einstieg in den Azure SignalR Service beschrieben. In dieser Schnellstartanleitung erstellen Sie eine Chatanwendung, indem Sie eine ASP.NET Core Web-App verwenden. Mit dieser App wird eine Verbindung mit Ihrer Azure SignalR Service-Ressource hergestellt, um Echtzeitupdates des Inhalts zu ermöglichen. Sie hosten die Webanwendung lokal und stellen Verbindungen mit mehreren Browserclients her. Von jedem Client aus können Inhaltsupdates per Pushvorgang an alle anderen Clients gesendet werden.

Sie können einen beliebigen Code-Editor nutzen, um die Schritte dieser Schnellstartanleitung auszuführen. Eine Option ist Visual Studio Code, das auf Windows-, macOS- und Linux-Plattformen verfügbar ist.

Der Code für dieses Tutorial kann aus dem GitHub-Repository „AzureSignalR-samples“ heruntergeladen werden. Außerdem können Sie die in dieser Schnellstartanleitung verwendeten Azure-Ressourcen erstellen, indem Sie Erstellen eines SignalR-Service-Skripts folgen.

Wenn Sie kein Azure-Abonnement besitzen, erstellen Sie ein kostenloses Konto, bevor Sie beginnen.

Bist du bereit?

Voraussetzungen

Treten Probleme auf? Verwenden Sie den Leitfaden zur Problembehandlung, oder informieren Sie uns.

Erstellen einer Azure SignalR-Ressource

In diesem Abschnitt erstellen Sie eine einfache Azure SignalR-Instanz für Ihre App. In den folgenden Schritten wird das Azure-Portal für die Erstellung einer neuen Instanz verwendet. Sie können jedoch auch die Azure CLI verwenden. Weitere Informationen finden Sie unter dem Befehl az signalr create in der Azure SignalR Service-CLI-Referenz.

  1. Melden Sie sich beim Azure-Portal an.
  2. Wählen Sie links oben auf der Seite die Option + Ressource erstellen aus.
  3. Geben Sie auf der Seite Ressource erstellen im Textfeld Dienste und Marketplace durchsuchen den Text signalr ein und wählen Sie dann SignalR Service aus der Liste aus.
  4. Klicken Sie auf der Seite SignalR Service auf Erstellen.
  5. Geben Sie auf der Registerkarte Grundlagen die grundlegenden Informationen für Ihre neue SignalR Dienstinstanz ein. Geben Sie die folgenden Werte ein:
Feld Empfohlener Wert BESCHREIBUNG
Abonnement Auswählen Ihres Abonnements Wählen Sie das Abonnement aus, das Sie verwenden möchten, um eine neue SignalR Service-Instanz zu erstellen.
Ressourcengruppe Erstellen einer Ressourcengruppe namens SignalRTestResources Wählen Sie eine Ressourcengruppe für Ihre SignalR-Ressource aus, oder erstellen Sie eine. Es ist hilfreich, für dieses Tutorial eine neue Ressourcengruppe zu erstellen, anstatt eine vorhandene Ressourcengruppe zu verwenden. Löschen Sie die Ressourcengruppe, um nach Abschluss des Tutorials Ressourcen freizugeben.

Durch das Löschen einer Ressourcengruppe werden auch alle Ressourcen dieser Gruppe gelöscht. Diese Aktion kann nicht rückgängig gemacht werden. Bevor Sie eine Ressourcengruppe löschen, stellen Sie sicher, dass sie keine Ressourcen enthält, die Sie behalten möchten.

Weitere Informationen finden Sie unter Verwenden von Ressourcengruppen zum Verwalten von Azure-Ressourcen.
Ressourcenname testsignalr Geben Sie für die SignalR-Ressource einen eindeutigen Ressourcennamen ein. Wenn testsignalr bereits in Ihrer Region belegt ist, fügen Sie Ziffern oder Zeichen hinzu, bis der Name eindeutig ist.

Der Name muss zwischen 1 und 63 Zeichen lang sein und darf nur Zahlen, Buchstaben und den Bindestrich (-) enthalten. Der Name darf weder mit dem Bindestrich beginnen oder enden noch mehrere aufeinanderfolgende Bindestriche enthalten.
Region Wählen Sie Ihre Region aus. Wählen Sie die entsprechende Region für Ihre neue SignalR Service-Instanz aus.

Azure SignalR Service ist derzeit nicht in allen Regionen verfügbar. Weitere Informationen finden Sie unter Verfügbare Produkte nach Region.
Preisstufe Klicken Sie auf Ändern und dann auf Free (nur Dev/Test). Klicken Sie auf Auswählen, um Ihre Tarifauswahl zu bestätigen. Azure SignalR Service bietet drei Tarife: Free, Standard und Premium. Für Tutorials wird der Tarif Free verwendet, sofern in den Voraussetzungen nichts anderes angegeben ist.

Weitere Informationen zu den Funktionsunterschieden zwischen Tarifen und Preisen finden Sie unter Azure SignalR Service – Preise.
Dienstmodus Auswählen des entsprechenden Dienstmodus Verwenden Sie Standard, wenn Sie die SignalR-Hublogik in Ihren Web-Apps hosten und den SignalR-Dienst als Proxy verwenden. Verwenden Sie Serverlos, wenn Sie serverlose Technologien wie Azure Functions verwenden, um die SignalR-Hublogik zu hosten.

Der Klassische Modus ist nur zur Abwärtskompatibilität vorgesehen und wird nicht empfohlen.

Weitere Informationen finden Sie unter Dienstmodi in Azure SignalR Service.

Sie müssen die Einstellungen auf den Registerkarten Netzwerk und Tags für die SignalR-Tutorials nicht ändern.

  1. Klicken Sie unten auf der Registerkarte Grundlagen auf die Schaltfläche Überprüfen und erstellen.
  2. Überprüfen Sie auf der Registerkarte Überprüfen und erstellen die Werte und klicken Sie dann auf Erstellen. Die Bereitstellung dauert etwas.
  3. Klicken Sie nach Abschluss der Bereitstellung auf die Schaltfläche Zu Ressource wechseln.
  4. Klicken Sie auf der SignalR-Ressourcenseite im Menü auf der linken Seite unter Einstellungen auf Schlüssel.
  5. Kopieren Sie die Verbindungszeichenfolge für den Primärschlüssel. Sie benötigen diese Verbindungszeichenfolge später in diesem Tutorial, um Ihre App zu konfigurieren.

Erstellen einer ASP.NET Core-Web-App

In diesem Abschnitt verwenden Sie die .NET Core-Befehlszeilenschnittstelle (CLI), um ein ASP.NET Core MVC-Web-App-Projekt zu erstellen. Der Vorteil bei Verwendung der .NET Core-CLI gegenüber Visual Studio ist, dass sie für alle Windows-, macOS- und Linux-Plattformen verfügbar ist.

  1. Erstellen Sie einen Ordner für Ihr Projekt. In dieser Schnellstartanleitung wird der Ordner chattest verwendet.

  2. Führen Sie im neuen Ordner den folgenden Befehl aus, um das Projekt zu erstellen:

    dotnet new web
    

Hinzufügen des Geheimnis-Managers

In diesem Abschnitt fügen Sie Ihrem Projekt das Geheimnis-Manager-Tool hinzu. Im Geheimnis-Manager-Tool werden sensible Daten für die Entwicklungsarbeit außerhalb Ihrer Projektstruktur gespeichert. Mit diesem Ansatz können Sie verhindern, dass App-Geheimnisse versehentlich im Quellcode angegeben werden.

  1. Initiieren Sie UserSecretsId im Ordner, indem Sie den folgenden Befehl ausführen:

    dotnet user-secrets init
    
  2. Fügen Sie dem Geheimnis-Manager ein Geheimnis mit dem Namen Azure:SignalR:ConnectionString hinzu.

    Dieses Geheimnis enthält die Verbindungszeichenfolge für den Zugriff auf Ihre SignalR Service-Ressource. Azure:SignalR:ConnectionString ist der Standardkonfigurationsschlüssel, nach dem SignalR sucht, um eine Verbindung herzustellen. Ersetzen Sie den Wert im folgenden Befehl durch die Verbindungszeichenfolge für Ihre SignalR Service-Ressource.

    Sie müssen diesen Befehl in demselben Verzeichnis wie die csproj-Datei ausführen.

    dotnet user-secrets set Azure:SignalR:ConnectionString "<Your connection string>"
    

    Der Geheimnis-Manager wird nur verwendet, um die Web-App zu testen, während sie lokal gehostet wird. In einem späteren Tutorial stellen Sie die Chat-Web-App dann in Azure bereit. Nachdem Sie die Web-App in Azure bereitgestellt haben, verwenden Sie eine Anwendungseinstellung, anstatt die Verbindungszeichenfolge im Geheimnis-Manager zu speichern.

    Auf dieses Geheimnis wird mit der Konfigurations-API zugegriffen. Ein Doppelpunkt (:) kann im Konfigurationsnamen mit der Konfigurations-API auf allen unterstützten Plattformen verwendet werden. Siehe Konfiguration nach Umgebung.

Hinzufügen von Azure SignalR zur Web-App

  1. Fügen Sie einen Verweis auf das NuGet-Paket Microsoft.Azure.SignalR hinzu, indem Sie den folgenden Befehl ausführen:

    dotnet add package Microsoft.Azure.SignalR
    
  2. Öffnen Sie Program.cs, und aktualisieren Sie den Code wie folgt – er ruft die Methoden AddSignalR() und AddAzureSignalR() auf, um Azure SignalR Service zu verwenden:

    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddSignalR().AddAzureSignalR();
    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseRouting();
    app.UseStaticFiles();
    app.MapHub<ChatSampleHub>("/chat");
    app.Run();
    

    Wenn kein Parameter an AddAzureSignalR() übergeben wird, verwendet er den Standardkonfigurationsschlüssel für die Verbindungszeichenfolge der SignalR Service-Ressource. Der Standardkonfigurationsschlüssel lautet Azure:SignalR:ConnectionString. Außerdem wird ChatSampleHub verwendet, was im folgenden Abschnitt erstellt wird.

Hinzufügen einer Hubklasse

In SignalR ist ein Hub eine Kernkomponente, über die eine Reihe von Methoden verfügbar gemacht wird, die vom Client aufgerufen werden können. In diesem Abschnitt definieren Sie eine Hubklasse mit zwei Methoden:

  • BroadcastMessage: Mit dieser Methode wird eine Nachricht an alle Clients übertragen.
  • Echo: Mit dieser Methode wird eine Nachricht zurück an den Aufrufer gesendet.

Für beide Methoden wird die Schnittstelle Clients genutzt, die über das ASP.NET Core SignalR SDK bereitgestellt wird. Mit dieser Schnittstelle haben Sie Zugriff auf alle verbundenen Clients und können Inhalt per Pushvorgang auf die Clients übertragen.

  1. Fügen Sie in Ihrem Projektverzeichnis einen neuen Ordner mit dem Namen Hub hinzu. Fügen Sie dem neuen Ordner eine neue Hubcodedatei mit dem Namen ChatSampleHub.cs hinzu.

  2. Fügen Sie ChatSampleHub.cs den folgenden Code hinzu, um Ihre Hubklasse zu definieren, und speichern Sie die Datei.

    using Microsoft.AspNetCore.SignalR;
    
    public class ChatSampleHub : Hub
    {
        public Task BroadcastMessage(string name, string message) =>
            Clients.All.SendAsync("broadcastMessage", name, message);
    
        public Task Echo(string name, string message) =>
            Clients.Client(Context.ConnectionId)
                    .SendAsync("echo", name, $"{message} (echo from server)");
    }
    

Hinzufügen der Clientschnittstelle für die Web-App

Die Clientbenutzeroberfläche für diese Chatraum-App besteht aus HTML- und JavaScript-Code in einer Datei mit dem Namen index.html, die im Verzeichnis wwwroot enthalten ist.

Kopieren Sie die Datei css/site.css aus dem Ordner wwwroot des Beispielrepositorys. Ersetzen Sie die css/site.css-Datei Ihres Projekts durch die von Ihnen kopierte Datei.

Erstellen Sie eine neue Datei im Verzeichnis wwwroot mit dem Namen index.html, kopieren Sie den folgenden HTML-Code, und fügen Sie ihn in die neu erstellte Datei ein.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
  <meta name="viewport" content="width=device-width">
  <meta http-equiv="Pragma" content="no-cache" />
  <meta http-equiv="Expires" content="0" />
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet" />
  <link href="css/site.css" rel="stylesheet" />
  <title>Azure SignalR Group Chat</title>
</head>
<body>
  <h2 class="text-center" style="margin-top: 0; padding-top: 30px; padding-bottom: 30px;">Azure SignalR Group Chat</h2>
  <div class="container" style="height: calc(100% - 110px);">
    <div id="messages" style="background-color: whitesmoke; "></div>
    <div style="width: 100%; border-left-style: ridge; border-right-style: ridge;">
      <textarea id="message" style="width: 100%; padding: 5px 10px; border-style: hidden;"
        placeholder="Type message and press Enter to send..."></textarea>
    </div>
    <div style="overflow: auto; border-style: ridge; border-top-style: hidden;">
      <button class="btn-warning pull-right" id="echo">Echo</button>
      <button class="btn-success pull-right" id="sendmessage">Send</button>
    </div>
  </div>
  <div class="modal alert alert-danger fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <div>Connection Error...</div>
          <div><strong style="font-size: 1.5em;">Hit Refresh/F5</strong> to rejoin. ;)</div>
        </div>
      </div>
    </div>
  </div>

  <!--Reference the SignalR library. -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>

  <!--Add script to update the page and send messages.-->
  <script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function () {
      function getUserName() {
        function generateRandomName() {
          return Math.random().toString(36).substring(2, 10);
        }

        // Get the user name and store it to prepend to messages.
        var username = generateRandomName();
        var promptMessage = "Enter your name:";
        do {
          username = prompt(promptMessage, username);
          if (!username || username.startsWith("_") || username.indexOf("<") > -1 || username.indexOf(">") > -1) {
            username = "";
            promptMessage = "Invalid input. Enter your name:";
          }
        } while (!username)
        return username;
      }

      username = getUserName();
      // Set initial focus to message input box.
      var messageInput = document.getElementById("message");
      messageInput.focus();

      function createMessageEntry(encodedName, encodedMsg) {
        var entry = document.createElement("div");
        entry.classList.add("message-entry");
        if (encodedName === "_SYSTEM_") {
          entry.innerHTML = encodedMsg;
          entry.classList.add("text-center");
          entry.classList.add("system-message");
        } else if (encodedName === "_BROADCAST_") {
          entry.classList.add("text-center");
          entry.innerHTML = `<div class="text-center broadcast-message">${encodedMsg}</div>`;
        } else if (encodedName === username) {
          entry.innerHTML = `<div class="message-avatar pull-right">${encodedName}</div>` +
            `<div class="message-content pull-right">${encodedMsg}<div>`;
        } else {
          entry.innerHTML = `<div class="message-avatar pull-left">${encodedName}</div>` +
            `<div class="message-content pull-left">${encodedMsg}<div>`;
        }
        return entry;
      }

      function appendMessage(encodedName, encodedMsg) {
        var messageEntry = createMessageEntry(encodedName, encodedMsg);
        var messageBox = document.getElementById("messages");
        messageBox.appendChild(messageEntry);
        messageBox.scrollTop = messageBox.scrollHeight;
      }

      function bindConnectionMessage(connection) {
        var messageCallback = function (name, message) {
          if (!message) return;
          // Html encode display name and message.
          var encodedName = name;
          var encodedMsg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
          appendMessage(encodedName, encodedMsg);
        };
        // Create a function that the hub can call to broadcast messages.
        connection.on("broadcastMessage", messageCallback);
        connection.on("echo", messageCallback);
        connection.onclose(onConnectionError);
      }

      function onConnected(connection) {
        console.log("connection started");
        connection.send("broadcastMessage", "_SYSTEM_", username + " JOINED");
        document.getElementById("sendmessage").addEventListener("click", function (event) {
          // Call the broadcastMessage method on the hub.
          if (messageInput.value) {
            connection.send("broadcastMessage", username, messageInput.value)
              .catch((e) => appendMessage("_BROADCAST_", e.message));
          }

          // Clear text box and reset focus for next comment.
          messageInput.value = "";
          messageInput.focus();
          event.preventDefault();
        });
        document.getElementById("message").addEventListener("keypress", function (event) {
          if (event.keyCode === 13) {
            event.preventDefault();
            document.getElementById("sendmessage").click();
            return false;
          }
        });
        document.getElementById("echo").addEventListener("click", function (event) {
          // Call the echo method on the hub.
          connection.send("echo", username, messageInput.value);

          // Clear text box and reset focus for next comment.
          messageInput.value = "";
          messageInput.focus();
          event.preventDefault();
        });
      }

      function onConnectionError(error) {
        if (error && error.message) {
          console.error(error.message);
        }
        var modal = document.getElementById("myModal");
        modal.classList.add("in");
        modal.style = "display: block;";
      }

      var connection = new signalR.HubConnectionBuilder()
        .withUrl("/chat")
        .build();
      bindConnectionMessage(connection);
      connection.start()
        .then(function () {
          onConnected(connection);
        })
        .catch(function (error) {
          console.error(error.message);
        });
    });
  </script>
</body>
</html>

Im Code in index.html wird HubConnectionBuilder.build() aufgerufen, um eine HTTP-Verbindung mit der Azure SignalR-Ressource herzustellen.

Wenn die Verbindungsherstellung erfolgreich ist, wird diese Verbindung an bindConnectionMessage übergeben, wo Ereignishandler für eingehende Pushvorgänge für Inhalte an den Client hinzugefügt werden.

HubConnection.start() startet die Kommunikation mit dem Hub. Dann fügt onConnected() die Schaltfläche für Ereignishandler hinzu. Diese Handler nutzen die Verbindung, um für diesen Client das Übertragen von Inhaltsupdates per Pushvorgang an alle verbundenen Clients zu ermöglichen.

Lokales Erstellen und Ausführen der App

  1. Führen Sie den folgenden Befehl aus, um die Web-App lokal auszuführen:

    dotnet run
    

    Die App wird lokal mit der Ausgabe gehostet, die die localhost-URL enthält, z. B. wie folgt:

    Building...
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: http://localhost:5000
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    info: Microsoft.Hosting.Lifetime[0]
          Hosting environment: Development
    
  2. Öffnen Sie zwei Browserfenster. Wechseln Sie in jedem Browser zu der localhost-URL, die im Ausgabefenster angezeigt wird, z. B. http://localhost:5000/ wie im obigen Ausgabefenster gezeigt. Sie werden aufgefordert, Ihren Namen einzugeben. Geben Sie einen Clientnamen für beide Clients ein, und testen Sie das Übertragen von Nachrichteninhalten zwischen den Clients per Pushvorgang über die Schaltfläche Send (Senden).

    Example of an Azure SignalR group chat

Bereinigen von Ressourcen

Falls Sie mit dem nächsten Tutorial fortfahren, können Sie die in dieser Schnellstartanleitung erstellten Ressourcen beibehalten und wiederverwenden.

Wenn Sie die Schnellstart-Beispielanwendung nicht mehr benötigen, können Sie die in dieser Schnellstartanleitung erstellten Azure-Ressourcen löschen, um das Anfallen von Kosten zu vermeiden.

Wichtig

Das Löschen einer Ressourcengruppe kann nicht rückgängig gemacht werden und umfasst alle Ressourcen dieser Gruppe. Achten Sie daher darauf, dass Sie nicht versehentlich die falsche Ressourcengruppe oder die falschen Ressourcen löschen. Falls Sie die Ressourcen in diesem Beispiel in einer vorhandenen Ressourcengruppe erstellt haben, die beizubehaltende Ressourcen enthält, können Sie jede Ressource einzeln über ihr Blatt löschen, statt die Ressourcengruppe zu löschen.

Melden Sie sich beim Azure-Portal an, und klicken Sie auf Ressourcengruppen.

Geben Sie im Textfeld Nach Name filtern den Namen Ihrer Ressourcengruppe ein. In dieser Schnellstartanleitung wurde eine Ressourcengruppe mit dem Namen SignalRTestResources verwendet. Wählen Sie in Ihrer Ressourcengruppe in der Ergebnisliste die Auslassungspunkte (...) > Ressourcengruppe löschen aus.

Selections for deleting a resource group

Sie werden aufgefordert, das Löschen der Ressourcengruppe zu bestätigen. Geben Sie zur Bestätigung den Namen Ihrer Ressourcengruppe ein, und klicken Sie auf Löschen.

Daraufhin werden die Ressourcengruppe und alle darin enthaltenen Ressourcen gelöscht.

Treten Probleme auf? Verwenden Sie den Leitfaden zur Problembehandlung, oder informieren Sie uns.

Nächste Schritte

In diesem Schnellstart haben Sie eine neue Azure SignalR Service-Ressource erstellt. Sie haben sie dann mit einer ASP.NET Core-Web-App verwendet, um Inhaltsaktualisierungen in Echtzeit auf mehrere verbundene Clients per Pushvorgang zu übertragen. Weitere Informationen zur Verwendung des Azure SignalR Service finden Sie im Tutorial, in dem es um die Authentifizierung geht.