Szybki start: tworzenie pokoju rozmów przy użyciu usługi SignalR Service

Usługa Azure SignalR Service to usługa platformy Azure, która ułatwia deweloperom tworzenie aplikacji internetowych z funkcjami działającymi w czasie rzeczywistym.

W tym artykule pokazano, jak rozpocząć pracę z usługą Azure SignalR Service. W tym przewodniku Szybki start utworzysz aplikację do czatu przy użyciu aplikacji internetowej ASP.NET Core. Ta aplikacja nawiąże połączenie z zasobem usługi Azure SignalR Service, aby umożliwić aktualizacje zawartości w czasie rzeczywistym. Aplikację internetową hostujesz lokalnie i połączysz się z wieloma klientami przeglądarki. Każdy klient będzie mógł wypychać aktualizacje zawartości do innych klientów.

Do wykonania kroków tego przewodnika Szybki start możesz użyć dowolnego edytora kodu. Jedną z opcji jest program Visual Studio Code, który jest dostępny na platformach Windows, macOS i Linux.

Kod dla tego samouczka jest dostępny do pobrania w repozytorium GitHub o nazwie AzureSignalR-samples. Zasoby platformy Azure używane w tym przewodniku Szybki start można utworzyć, wykonując czynności opisane w artykule Create a SignalR Service script (Tworzenie skryptu usługi SignalR Service).

Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto.

Chcesz rozpocząć?

Wymagania wstępne

Masz problemy? Wypróbuj przewodnik rozwiązywania problemów lub daj nam znać.

Tworzenie zasobu usługi Azure SignalR

W tej sekcji utworzysz podstawowe wystąpienie usługi Azure SignalR do użycia dla aplikacji. Poniższe kroki umożliwiają utworzenie nowego wystąpienia za pomocą witryny Azure Portal, ale można również użyć interfejsu wiersza polecenia platformy Azure. Aby uzyskać więcej informacji, zobacz polecenie az signalr create w dokumentacji interfejsu wiersza polecenia usługi Azure SignalR Service.

  1. Zaloguj się w witrynie Azure Portal.
  2. W lewym górnym rogu strony wybierz pozycję + Utwórz zasób.
  3. Na stronie Tworzenie zasobu w polu tekstowym usługa wyszukiwania s i marketplace wprowadź signalr, a następnie wybierz pozycję SignalR Service z listy.
  4. Na stronie SignalR Service wybierz pozycję Utwórz.
  5. Na karcie Podstawy wprowadź podstawowe informacje dotyczące nowego wystąpienia usługi SignalR Service. Wprowadź następujące wartości:
Pole Sugerowana wartość opis
Subskrypcja Wybierz swoją subskrypcję Wybierz subskrypcję, której chcesz użyć, aby utworzyć nowe wystąpienie usługi SignalR Service.
Grupa zasobów: Tworzenie grupy zasobów o nazwie SignalRTestResources Wybierz lub utwórz grupę zasobów dla zasobu usługi SignalR. Warto utworzyć nową grupę zasobów na potrzeby tego samouczka zamiast używać istniejącej grupy zasobów. Aby zwolnić zasoby po ukończeniu samouczka, usuń grupę zasobów.

Usunięcie grupy zasobów powoduje również usunięcie wszystkich zasobów należących do grupy. Tej akcji nie można cofnąć. Przed usunięciem grupy zasobów upewnij się, że nie zawiera ona zasobów, które chcesz zachować.

Więcej informacji można znaleźć w temacie Using resource groups to manage your Azure resources (Używanie grup zasobów do zarządzania zasobami platformy Azure).
Nazwa zasobu testsignalr Podaj unikatową nazwę zasobu do użycia dla zasobu usługi SignalR. Jeśli testsignalr jest już wykonany w Twoim regionie, dodaj cyfrę lub znak, dopóki nazwa nie będzie unikatowa.

Nazwa musi być ciągiem od 1 do 63 znaków i zawierać tylko cyfry, litery i znak łącznika (-). Nazwa nie może zaczynać ani kończyć się znakiem łącznika, a kolejne znaki łącznika są nieprawidłowe.
Region Wybierz region Wybierz odpowiedni region dla nowego wystąpienia usługi SignalR Service.

Usługa Azure SignalR Service nie jest obecnie dostępna we wszystkich regionach. Aby uzyskać więcej informacji, zobacz Dostępność regionów usługi Azure SignalR Service
Warstwa cenowa Wybierz pozycję Zmień , a następnie wybierz pozycję Bezpłatna (tylko tworzenie i testowanie). Wybierz pozycję Wybierz , aby potwierdzić wybór warstwy cenowej. Usługa Azure SignalR Service ma trzy warstwy cenowe: Bezpłatna, Standardowa i Premium. Samouczki korzystają z warstwy Bezpłatna, chyba że określono inaczej w wymaganiach wstępnych.

Aby uzyskać więcej informacji o różnicach funkcjonalności między warstwami i cenami, zobacz Cennik usługi Azure SignalR Service
Tryb usługi Wybieranie odpowiedniego trybu usługi Użyj wartości Domyślnej podczas hostowania logiki centrum SignalR w aplikacjach internetowych i używania usługi SignalR jako serwera proxy. Używaj technologii bezserwerowych , takich jak Azure Functions, do hostowania logiki centrum SignalR.

Tryb klasyczny jest przeznaczony tylko dla zgodności z poprzednimi wersjami i nie jest zalecany do użycia.

Aby uzyskać więcej informacji, zobacz Tryb usługi w usłudze Azure SignalR Service.

Nie musisz zmieniać ustawień na kartach Sieć i tagi samouczków usługi SignalR.

  1. Wybierz przycisk Przejrzyj i utwórz w dolnej części karty Podstawy.
  2. Na karcie Przeglądanie i tworzenie przejrzyj wartości, a następnie wybierz pozycję Utwórz. Ukończenie wdrożenia zajmuje kilka chwil.
  3. Po zakończeniu wdrażania wybierz przycisk Przejdź do zasobu .
  4. Na stronie zasobu usługi SignalR wybierz pozycję Klucze z menu po lewej stronie w obszarze Ustawienia.
  5. Skopiuj ciąg Połączenie ion dla klucza podstawowego. Ta parametry połączenia jest potrzebna do skonfigurowania aplikacji w dalszej części tego samouczka.

Tworzenie aplikacji internetowej ASP.NET Core

W tej sekcji użyjesz interfejsu wiersza polecenia platformy .NET Core do utworzenia projektu aplikacji internetowej platformy ASP.NET Core MVC. Zaletą korzystania z interfejsu wiersza polecenia platformy .NET Core za pośrednictwem programu Visual Studio jest to, że jest ona dostępna na platformach Windows, macOS i Linux.

  1. Utwórz folder dla projektu. W tym przewodniku Szybki start jest używany folder chattest .

  2. W nowym folderze uruchom następujące polecenie, aby utworzyć projekt:

    dotnet new web
    

Dodawanie narzędzia Secret Manager do projektu

W tej sekcji dodasz narzędzie Secret Manager do projektu. Narzędzie Secret Manager przechowuje poufne dane na potrzeby prac programistycznych poza drzewem projektu. Takie podejście pomaga zapobiec przypadkowemu udostępnianiu wpisów tajnych aplikacji w kodzie źródłowym.

  1. W folderze init UserSecretsId uruchom następujące polecenie:

    dotnet user-secrets init
    
  2. Dodaj wpis tajny o nazwie Azure:SignalR:ConnectionString do narzędzia Secret Manager.

    Ten wpis tajny będzie zawierać parametry połączenia umożliwiające dostęp do zasobu usługi SignalR Service. Azure:SignalR:Połączenie ionString to domyślny klucz konfiguracji, którego usługa SignalR szuka do nawiązania połączenia. Zastąp wartość w poniższym poleceniu parametry połączenia dla zasobu usługi SignalR Service.

    To polecenie należy uruchomić w tym samym katalogu co csproj plik.

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

    Menedżer wpisów tajnych będzie używany tylko do testowania aplikacji internetowej, gdy jest hostowana lokalnie. W późniejszym samouczku wdrożysz aplikację internetową czatu na platformie Azure. Po wdrożeniu aplikacji internetowej na platformie Azure użyjesz ustawienia aplikacji zamiast przechowywania parametry połączenia za pomocą programu Secret Manager.

    Dostęp do tego wpisu tajnego jest uzyskiwany za pomocą interfejsu API konfiguracji. Dwukropek (:) działa w nazwie konfiguracji z interfejsem API konfiguracji na wszystkich obsługiwanych platformach. Zobacz Konfiguracja według środowiska.

Dodawanie usługi Azure SignalR do aplikacji internetowej

  1. Dodaj odwołanie do Microsoft.Azure.SignalR pakietu NuGet, uruchamiając następujące polecenie:

    dotnet add package Microsoft.Azure.SignalR
    
  2. Otwórz plik Program.cs i zaktualizuj kod w następujący sposób, wywołuje AddSignalR() metody i AddAzureSignalR() w celu użycia usługi Azure SignalR Service:

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

    Nie przekazuje parametru, aby AddAzureSignalR() oznaczać, że używa domyślnego klucza konfiguracji dla zasobu usługi SignalR Service parametry połączenia. Domyślnym kluczem konfiguracji jest Azure:SignalR:Połączenie ionString. Zostanie również użyta ChatSampleHub funkcja , która zostanie utworzona w poniższej sekcji.

Dodawanie klasy centrum

W usłudze SignalR koncentrator jest podstawowym składnikiem, który uwidacznia zestaw metod, które mogą być wywoływane przez klienta. W tej sekcji klasa centrum jest definiowania za pomocą dwóch metod:

  • BroadcastMessage: ta metoda rozgłasza komunikat do wszystkich klientów.
  • Echo: ta metoda wysyła komunikat z powrotem do elementu wywołującego.

Obie metody używają interfejsu Clients , który zapewnia zestaw SDK ASP.NET Core SignalR. Ten interfejs zapewnia dostęp do wszystkich połączonych klientów, dzięki czemu można wypychać zawartość do klientów.

  1. W katalogu projektu dodaj nowy folder o nazwie Hub. Dodaj nowy plik kodu centrum o nazwie ChatSampleHub.cs do nowego folderu.

  2. Dodaj następujący kod do pliku ChatSampleHub.cs , aby zdefiniować klasę centrum i zapisać plik.

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

Dodawanie interfejsu klienta dla aplikacji internetowej

Interfejs użytkownika klienta dla tej aplikacji pokoju rozmów będzie zawierać kod HTML i JavaScript w pliku o nazwie index.html w katalogu wwwroot .

Skopiuj plik css/site.css z folderu wwwroot repozytorium przykładów. Zastąp skopiowany plik css/site.css projektu.

Utwórz nowy plik w katalogu wwwroot o nazwie index.html, skopiuj i wklej następujący kod HTML do nowo utworzonego pliku.

<!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>

Kod w pliku index.html wywołuje HubConnectionBuilder.build() , aby nawiązać połączenie HTTP z zasobem usługi Azure SignalR.

Jeśli połączenie zostanie nawiązane pomyślnie, zostanie przekazane do metody bindConnectionMessage, która dodaje procedury obsługi zdarzeń dla przychodzących wypchnięć zawartości do klienta.

Metoda HubConnection.start() uruchamia komunikację z centrum. onConnected() Następnie dodaje programy obsługi zdarzeń przycisku. Te procedury obsługi używają połączenia w celu umożliwienia temu klientowi wpychania aktualizacji zawartości do wszystkich połączonych klientów.

Lokalne kompilowanie i uruchamianie aplikacji

  1. Uruchom następujące polecenie, aby uruchomić aplikację internetową lokalnie:

    dotnet run
    

    Aplikacja będzie hostowana lokalnie z danymi wyjściowymi zawierającymi adres URL hosta lokalnego, na przykład jako następujące:

    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. Otwórz dwa okna przeglądarki. W każdej przeglądarce przejdź do adresu URL hosta lokalnego wyświetlanego w oknie danych wyjściowych, na przykład, http://localhost:5000/ jak pokazano w powyższym oknie danych wyjściowych. Zostanie wyświetlony monit o wprowadzenie swojej nazwy. Wprowadź nazwę klienta zarówno dla klientów, jak i przetestuj wypychanie zawartości komunikatów między obydwoma klientami przy użyciu przycisku Wyślij .

    Example of an Azure SignalR group chat

Czyszczenie zasobów

Jeśli przejdziesz do następnego samouczka, możesz zachować zasoby utworzone w tym przewodniku Szybki start i użyć ich ponownie.

Jeśli skończysz z przykładową aplikacją Szybkiego startu, możesz usunąć zasoby platformy Azure utworzone w tym przewodniku Szybki start, aby uniknąć naliczania opłat.

Ważne

Usunięcie grupy zasobów jest nieodwracalne i obejmuje wszystkie zasoby w tej grupie. Uważaj, aby nie usunąć przypadkowo niewłaściwych zasobów lub niewłaściwej grupy zasobów. Jeśli zasoby utworzone w tym przykładzie zostały utworzone w istniejącej grupie zasobów zawierającej zasoby, które chcesz zachować, możesz usunąć każdy zasób oddzielnie z bloku zamiast usuwać grupę zasobów.

Zaloguj się do witryny Azure Portal i wybierz pozycję Grupy zasobów.

W polu tekstowym Filtruj według nazwy wpisz nazwę grupy zasobów. W instrukcjach dla tego przewodnika Szybki start używana była grupa zasobów o nazwie SignalRTestResources. Na liście wyników w grupie zasobów wybierz wielokropek (...) >Usuń grupę zasobów.

Selections for deleting a resource group

Zobaczysz prośbę o potwierdzenie usunięcia grupy zasobów. Wprowadź nazwę grupy zasobów, aby potwierdzić, a następnie wybierz pozycję Usuń.

Po krótkim czasie grupa zasobów i wszystkie jej zasoby zostaną usunięte.

Masz problemy? Wypróbuj przewodnik rozwiązywania problemów lub daj nam znać.

Następne kroki

W tym przewodniku Szybki start utworzono nowy zasób usługi Azure SignalR Service. Następnie użyto jej z aplikacją internetową ASP.NET Core do wypychania aktualizacji zawartości w czasie rzeczywistym do wielu połączonych klientów. Aby dowiedzieć się więcej na temat korzystania z usługi Azure SignalR Service, przejdź do samouczka demonstrującego uwierzytelnianie.