Udostępnij przez


Samouczek: tworzenie bezserwerowej aplikacji do czatów w czasie rzeczywistym za pomocą usług Azure Functions i Azure Web PubSub

Usługa Azure Web PubSub ułatwia tworzenie aplikacji internetowych do obsługi komunikatów w czasie rzeczywistym przy użyciu obiektów WebSocket i wzorca publikowania-subskrybowania. Usługa Azure Functions to bezserwerowa platforma, która pozwala uruchamiać kod bez zarządzania jakąkolwiek infrastrukturą. Z tego samouczka dowiesz się, jak za pomocą usługi Azure Web PubSub i usługi Azure Functions utworzyć aplikację bezserwerową z obsługą komunikatów w czasie rzeczywistym i wzorcem publikowania-subskrybowania.

W tym poradniku nauczysz się, jak:

  • Tworzenie bezserwerowej aplikacji do czatu w czasie rzeczywistym
  • Praca z powiązaniami wyzwalaczy funkcji Web PubSub i powiązaniami wyjściowymi
  • Wdróż funkcję do Azure Function App
  • Konfigurowanie uwierzytelniania platformy Azure
  • Konfigurowanie programu obsługi zdarzeń Web PubSub w celu kierowania zdarzeń i komunikatów do aplikacji

Ważne

Nieprzetworzone parametry połączenia są wyświetlane tylko w tym artykule w celach demonstracyjnych.

Parametry połączenia zawiera informacje o autoryzacji wymagane przez aplikację w celu uzyskania dostępu do usługi Azure Web PubSub. Klucz dostępu wewnątrz ciągu połączenia jest podobny do hasła głównego dla twojej usługi. W środowiskach produkcyjnych zawsze chroń klucze dostępu. Użyj usługi Azure Key Vault, aby bezpiecznie zarządzać kluczami i obracać je oraz zabezpieczać połączenie za pomocą usługi WebPubSubServiceClient.

Unikaj dystrybuowania kluczy dostępu do innych użytkowników, kodowania ich lub zapisywania ich w dowolnym miejscu w postaci zwykłego tekstu, który jest dostępny dla innych użytkowników. Obróć klucze, jeśli uważasz, że zostały naruszone.

Wymagania wstępne

  • Edytor kodu, taki jak Visual Studio Code

  • Node.js, wersja 18.x lub nowsza.

    Uwaga / Notatka

    Aby uzyskać więcej informacji na temat obsługiwanych wersji Node.js, zobacz dokumentację wersji środowiska uruchomieniowego usługi Azure Functions.

  • Azure Functions Core Tools (preferowana wersja 4 lub nowsza) do uruchamiania aplikacji funkcji platformy Azure lokalnie i wdrażania na platformie Azure.

  • Azure CLI do zarządzania zasobami platformy Azure.

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

Zaloguj się do Azure

Zaloguj się do witryny Azure Portal pod adresem https://portal.azure.com/ przy użyciu konta platformy Azure.

Tworzenie wystąpienia usługi Azure Web PubSub

Twoja aplikacja połączy się z wystąpieniem usługi Web PubSub na platformie Azure.

  1. Wybierz przycisk Nowy znajdujący się w lewym górnym rogu witryny Azure Portal. Na ekranie Nowy wpisz Web PubSub w polu wyszukiwania i naciśnij Enter. (Możesz również przeszukać usługę Azure Web PubSub z Web kategorii).

    Zrzut ekranu przedstawiający wyszukiwanie usługi Azure Web PubSub w portalu.

  2. Wybierz pozycję Web PubSub z wyników wyszukiwania, a następnie wybierz pozycję Utwórz.

  3. Wprowadź następujące ustawienia.

    Ustawienia Sugerowana wartość Opis
    Nazwa zasobu Nazwa unikatowa w skali globalnej Unikalna na skalę globalną nazwa identyfikująca nową instancję usługi Web PubSub. Prawidłowe znaki to a-z, , A-Z0-9i -.
    Subskrypcja Twoja subskrypcja Subskrypcja usługi Azure, w ramach której tworzona jest nowa instancja usługi Web PubSub.
    Grupa zasobów GrupaZasobówMoja Nazwa nowej grupy zasobów, w której ma zostać utworzone wystąpienie usługi Web PubSub.
    Lokalizacja Zachodnie stany USA Wybierz region blisko Ciebie.
    Poziom cenowy Bezpłatna Najpierw możesz bezpłatnie wypróbować usługę Azure Web PubSub. Dowiedz się więcej o warstwach cenowych usługi Azure Web PubSub
    Liczba jednostek - Liczba jednostek określa, ile połączeń może przyjąć instancja usługi Web PubSub. Każda jednostka obsługuje co najwyżej 1000 równoczesnych połączeń. Można to skonfigurować tylko w warstwie Standard.

    Zrzut ekranu przedstawiający tworzenie wystąpienia usługi Azure Web PubSub w portalu.

  4. Wybierz Utwórz, aby rozpocząć wdrażanie wystąpienia usługi Web PubSub.

Tworzenie funkcji

  1. Upewnij się, że masz zainstalowane narzędzia Azure Functions Core Tools . Następnie utwórz pusty katalog dla projektu. Uruchom polecenie w tym katalogu roboczym.

    func init --worker-runtime javascript --model V4
    
  2. Zainstaluj Microsoft.Azure.WebJobs.Extensions.WebPubSub.

    Potwierdź i zaktualizuj rozszerzenie Bundle host.json do wersji 4.* lub nowszej, aby uzyskać obsługę Web PubSub.

    {
      "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[4.*, 5.0.0)"
      }
    }
    
  3. index Utwórz funkcję do odczytu i hostowania statycznej strony internetowej dla klientów.

    func new -n index -t HttpTrigger
    
    • Zaktualizuj src/functions/index.js i skopiuj następujące kody.
      const { app } = require('@azure/functions');
      const { readFile } = require('fs/promises');
      
      app.http('index', {
          methods: ['GET', 'POST'],
          authLevel: 'anonymous',
          handler: async (context) => {
              const content = await readFile('index.html', 'utf8', (err, data) => {
                  if (err) {
                      context.err(err)
                      return
                  }
              });
      
              return { 
                  status: 200,
                  headers: { 
                      'Content-Type': 'text/html'
                  }, 
                  body: content, 
              };
          }
      });
      
  4. negotiate Utwórz funkcję, aby ułatwić klientom uzyskiwanie adresu URL połączenia z usługą przy użyciu tokenu dostępu.

    func new -n negotiate -t HttpTrigger
    

    Uwaga / Notatka

    W tym przykładzie użyjemy nagłówka tożsamości użytkownika Microsoft Entra IDx-ms-client-principal-name do pobrania userId. I to nie będzie działać w funkcji lokalnej. Możesz je opróżnić lub zmienić na inne sposoby uzyskiwania lub generowania userId podczas grania w środowisku lokalnym. Na przykład pozwól klientowi na wpisanie nazwy użytkownika i przekazanie jej w zapytaniu, na przykład ?user={$username} w przypadku wywołania negotiate funkcji w celu uzyskania adresu URL połączenia z usługą. W funkcji negotiate ustaw userId na wartość {query.user}.

    • Zaktualizuj src/functions/negotiate i skopiuj następujące kody.
      const { app, input } = require('@azure/functions');
      
      const connection = input.generic({
          type: 'webPubSubConnection',
          name: 'connection',
          userId: '{headers.x-ms-client-principal-name}',
          hub: 'simplechat'
      });
      
      app.http('negotiate', {
          methods: ['GET', 'POST'],
          authLevel: 'anonymous',
          extraInputs: [connection],
          handler: async (request, context) => {
              return { body: JSON.stringify(context.extraInputs.get('connection')) };
          },
      });
      
  5. Utwórz funkcję rozgłaszania message komunikatów klienta za pośrednictwem usługi.

    func new -n message -t HttpTrigger
    
    • Zaktualizuj src/functions/message.js i skopiuj następujące kody.
      const { app, output, trigger } = require('@azure/functions');
      
      const wpsMsg = output.generic({
          type: 'webPubSub',
          name: 'actions',
          hub: 'simplechat',
      });
      
      const wpsTrigger = trigger.generic({
          type: 'webPubSubTrigger',
          name: 'request',
          hub: 'simplechat',
          eventName: 'message',
          eventType: 'user'
      });
      
      app.generic('message', {
          trigger: wpsTrigger,
          extraOutputs: [wpsMsg],
          handler: async (request, context) => {
              context.extraOutputs.set(wpsMsg, [{
                  "actionName": "sendToAll",
                  "data": `[${context.triggerMetadata.connectionContext.userId}] ${request.data}`,
                  "dataType": request.dataType
              }]);
      
              return {
                  data: "[SYSTEM] ack.",
                  dataType: "text",
              };
          }
      });
      
  6. Dodaj pojedynczą stronę index.html klienta w folderze głównym projektu i skopiuj zawartość.

    <html>
      <body>
        <h1>Azure Web PubSub Serverless Chat App</h1>
        <div id="login"></div>
        <p></p>
        <input id="message" placeholder="Type to chat..." />
        <div id="messages"></div>
        <script>
          (async function () {
            let authenticated = window.location.href.includes(
              "?authenticated=true"
            );
            if (!authenticated) {
              // auth
              let login = document.querySelector("#login");
              let link = document.createElement("a");
              link.href = `${window.location.origin}/.auth/login/aad?post_login_redirect_url=/api/index?authenticated=true`;
              link.text = "login";
              login.appendChild(link);
            } else {
              // negotiate
              let messages = document.querySelector("#messages");
              let res = await fetch(`${window.location.origin}/api/negotiate`, {
                credentials: "include",
              });
              let url = await res.json();
              // connect
              let ws = new WebSocket(url.url);
              ws.onopen = () => console.log("connected");
              ws.onmessage = (event) => {
                let m = document.createElement("p");
                m.innerText = event.data;
                messages.appendChild(m);
              };
              let message = document.querySelector("#message");
              message.addEventListener("keypress", (e) => {
                if (e.charCode !== 13) return;
                ws.send(message.value);
                message.value = "";
              });
            }
          })();
        </script>
      </body>
    </html>
    

Tworzenie i wdrażanie aplikacji funkcji platformy Azure

Przed wdrożeniem kodu funkcji na platformie Azure należy utworzyć trzy zasoby:

  • Grupa zasobów, która jest kontenerem logicznym dla powiązanych zasobów.
  • Konto magazynowe, które służy do zarządzania stanem pracy i innymi informacjami o funkcjach.
  • Aplikacja funkcji, która udostępnia środowisko do wykonywania kodu funkcji. Aplikacja funkcji odpowiada lokalnemu projektowi funkcji i umożliwia grupowanie funkcji jako jednostki logicznej w celu łatwiejszego zarządzania, wdrażania i współdzielenia zasobów.

Użyj następujących poleceń, aby utworzyć te elementy.

  1. Jeśli jeszcze tego nie zrobiono, zaloguj się do platformy Azure:

    az login
    
  2. Utwórz grupę zasobów lub możesz to pominąć, ponownie używając istniejącej grupy zasobów usługi Azure Web PubSub.

    az group create -n WebPubSubFunction -l <REGION>
    
  3. Utwórz konto magazynu ogólnego przeznaczenia w grupie zasobów i regionie:

    az storage account create -n <STORAGE_NAME> -l <REGION> -g WebPubSubFunction
    
  4. Utwórz aplikację funkcji na platformie Azure:

    az functionapp create --resource-group WebPubSubFunction --consumption-plan-location <REGION> --runtime node --runtime-version 18 --functions-version 4 --name <FUNCIONAPP_NAME> --storage-account <STORAGE_NAME>
    

    Uwaga / Notatka

    Zapoznaj się z dokumentacją wersji środowiska uruchomieniowego usługi Azure Functions, aby ustawić --runtime-version parametr na obsługiwaną wartość.

  5. Wdróż projekt funkcji na platformie Azure:

    Po pomyślnym utworzeniu aplikacji funkcji na platformie Azure możesz przystąpić do wdrażania lokalnego projektu funkcji przy użyciu polecenia func azure functionapp publish .

    func azure functionapp publish <FUNCIONAPP_NAME>
    
  6. Skonfiguruj WebPubSubConnectionString dla aplikacji funkcji:

    Nieprzetworzone parametry połączenia są wyświetlane tylko w tym artykule w celach demonstracyjnych. W środowiskach produkcyjnych zawsze chroń klucze dostępu. Użyj usługi Azure Key Vault, aby bezpiecznie zarządzać kluczami i obracać je oraz zabezpieczać połączenie za pomocą usługi WebPubSubServiceClient.

    Najpierw znajdź zasób Web PubSub w Azure Portal i skopiuj ciąg połączenia z sekcji Klucze. Następnie przejdź do sekcji Ustawienia aplikacji funkcjonalnej w witrynie Azure Portal ->Ustawienia ->Zmienne środowiskowe. Dodaj nowy element w obszarze Ustawienia aplikacji, o nazwie równej WebPubSubConnectionString i wartości to parametry połączenia zasobu Web PubSub.

Konfigurowanie usługi Web PubSub Event Handler

W tym przykładzie używamy WebPubSubTrigger aby nasłuchiwać żądań wysyłanych do góry strumienia usługi. Dlatego usługa Web PubSub musi znać informacje o punkcie końcowym funkcjonalności w celu wysyłania żądań do docelowych klientów. Aplikacja funkcji platformy Azure wymaga klucza systemowego do zabezpieczenia metod webhook specyficznych dla danego rozszerzenia. W poprzednim kroku, po wdrożeniu Aplikacji Funkcji z funkcjami message, jesteśmy w stanie pobrać klucz systemowy.

Przejdź do portalu Azure -> znajdź zasób swojej aplikacji funkcji ->Klucze aplikacji ->Klucze systemowe ->webpubsub_extension. Skopiuj wartość jako <APP_KEY>.

Zrzut ekranu przedstawiający pobieranie kluczy systemowych funkcji.

Ustaw Event Handler w usłudze Azure Web PubSub. Przejdź do portalu Azure —> znajdź zasób Web PubSub —>Ustawienia. Dodaj nowe mapowanie ustawień centrum do jednej używanej funkcji. Zastąp elementy <FUNCTIONAPP_NAME> i <APP_KEY> na swoje.

  • Nazwa centrum: simplechat
  • Szablon adresu URL: https://<FUNCTIONAPP_NAME>.azurewebsites.net/runtime/webhooks/webpubsub?code=<APP_KEY>
  • Wzorzec zdarzenia użytkownika: *
  • Zdarzenia systemowe: -(Nie trzeba konfigurować w tym przykładzie)

Zrzut ekranu przedstawiający ustawianie programu obsługi zdarzeń.

Konfigurowanie w celu włączenia uwierzytelniania klienta

Przejdź do Azure Portal –> znajdź zasób aplikacji funkcji Azure –>Uwierzytelnianie. Kliknij Add identity provider. Ustaw ustawienia uwierzytelniania usługi App Service na Zezwalaj na nieuwierzytelniony dostęp, aby strona indeksu klienta mogła być odwiedzana przez użytkowników anonimowych przed przekierowaniem do uwierzytelniania. Następnie zapisz.

W tym miejscu wybieramy Microsoft jako dostawcę tożsamości, który używa x-ms-client-principal-name jako userId w funkcji negotiate. Poza tym można skonfigurować innych dostawców tożsamości, postępując zgodnie z linkami, i nie zapomnij odpowiednio zaktualizować wartości userId w funkcji negotiate.

Wypróbuj aplikację

Teraz możesz przetestować stronę z poziomu aplikacji funkcjonalnej: https://<FUNCTIONAPP_NAME>.azurewebsites.net/api/index. Zobacz zrzut ekranu.

  1. Kliknij login, aby się uwierzytelnić.
  2. Wpisz komunikat w polu wejściowym, aby porozmawiać.

W funkcji komunikatu przesyłamy komunikat wywołującego do wszystkich klientów i zwracamy wywołującego z komunikatem [SYSTEM] ack. Dzięki temu możemy wiedzieć w przykładowej migawce czatu, pierwsze cztery komunikaty pochodzą z bieżącego klienta, a ostatnie dwa komunikaty pochodzą z innego klienta.

Zrzut ekranu przedstawiający przykład czatu.

Uprzątnij zasoby

Jeśli nie zamierzasz nadal korzystać z tej aplikacji, usuń wszystkie zasoby utworzone przez ten dokument, wykonując następujące kroki, aby nie ponosić żadnych opłat:

  1. W witrynie Azure Portal wybierz grupy zasobów daleko po lewej stronie, a następnie wybierz utworzoną grupę zasobów. Możesz użyć pola wyszukiwania, aby znaleźć grupę zasobów według jej nazwy.

  2. W wyświetlonym oknie wybierz grupę zasobów, a następnie wybierz pozycję Usuń grupę zasobów.

  3. W nowym oknie wpisz nazwę grupy zasobów do usunięcia, a następnie wybierz pozycję Usuń.

Dalsze kroki

W tym przewodniku Szybki start przedstawiono sposób uruchamiania bezserwerowej aplikacji do czatu. Teraz możesz rozpocząć tworzenie własnej aplikacji.