Tutorial: Erstellen einer serverlosen Echtzeit-Chat-App mit Azure Functions und dem Azure Web PubSub-Dienst
Der Azure Web PubSub-Dienst unterstützt Sie beim einfachen Erstellen von Echtzeit-Messagingwebanwendungen mithilfe von WebSockets und des Veröffentlichen-Abonnieren-Musters. Azure Functions ist eine serverlose Plattform, mit der Sie Ihren Code ohne Verwaltung von Infrastruktur ausführen können. In diesem Tutorial erfahren Sie, wie Sie den Azure Web PubSub-Dienst und Azure Functions verwenden, um eine serverlose Anwendung mit Echtzeitmessaging und dem Veröffentlichen-Abonnieren-Muster zu erstellen.
In diesem Tutorial lernen Sie Folgendes:
- Erstellen einer serverlosen Echtzeit-Chat-App
- Arbeiten mit Web PubSub-Funktionstrigger- und -ausgabebindungen
- Bereitstellen der Funktion in der Azure-Funktions-App
- Konfigurieren der Azure-Authentifizierung
- Konfigurieren des Web PubSub-Ereignishandlers zum Weiterleiten von Ereignissen und Nachrichten an die Anwendung
Voraussetzungen
Ein Code-Editor wie Visual Studio Code
Node.js, Version 18.x oder höher.
Hinweis
Weitere Informationen zu den unterstützten Versionen von Node.js finden Sie in der Übersicht über die Runtimeversionen von Azure Functions.
Azure Functions Core Tools (v4 oder höher bevorzugt), um Azure Funktions-Apps lokal auszuführen und in Azure bereitzustellen.
Azure CLI zum Verwalten von Azure-Ressourcen
Wenn Sie kein Azure-Abonnement haben, erstellen Sie ein kostenloses Azure-Konto, bevor Sie beginnen.
Anmelden bei Azure
Melden Sie sich unter https://portal.azure.com/ mit Ihrem Azure-Konto beim Azure-Portal an.
Erstellen einer Azure Web PubSub-Dienstinstanz
Ihre Anwendung stellt eine Verbindung mit einer Instanz des Web PubSub-Diensts in Azure her.
Klicken Sie in der linken oberen Ecke des Azure-Portals auf die Schaltfläche „Neu“. Geben Sie im Bildschirm „Neu“ den Begriff Web PubSub in das Suchfeld ein, und drücken Sie die EINGABETASTE. (Sie können Azure Web PubSub auch in der Kategorie
Web
durchsuchen.)Wählen Sie in den Suchergebnissen Web PubSub und dann Erstellen aus.
Geben Sie folgende Einstellungen ein.
Einstellung Vorgeschlagener Wert BESCHREIBUNG Ressourcenname Global eindeutiger Name Der global eindeutige Name, welcher Ihre neue Web PubSub-Dienstinstanz identifiziert. Gültige Zeichen sind a-z
,A-Z
,0-9
und-
.Abonnement Ihr Abonnement Das Azure-Web PubSubAbonnement, unter dem diese neue Web PubSub-Dienstinstanz erstellt wird. Ressourcengruppe myResourceGroup Name für die neue Ressourcengruppe, in der Ihre Web PubSub-Dienstinstanz erstellt werden soll Location USA (Westen) Wählen Sie eine Region in Ihrer Nähe aus. Preisstufe Kostenlos Sie können Azure Web PubSub zuerst kostenlos ausprobieren. Erfahren Sie mehr über die Tarife des Azure Web PubSub-Diensts. Einheitenanzahl - Die Einheitenanzahl gibt an, wie viele Verbindungen Ihre Instanz des Web PubSub-Dienstes akzeptieren kann. Jede Einheit unterstützt höchstens 1.000 gleichzeitige Verbindungen. Dies kann nur im Tarif „Standard“ konfiguriert werden. Wählen Sie Erstellen aus, um mit der Bereitstellung der Instanz des Web PubSub-Dienstes zu beginnen.
Erstellen der Funktionen
Stellen Sie sicher, dass Azure Functions Core Tools installiert ist. Erstellen Sie dann ein leeres Verzeichnis für das Projekt. Führen Sie den Befehl unter diesem Arbeitsverzeichnis aus.
func init --worker-runtime javascript --model V4
Installieren von
Microsoft.Azure.WebJobs.Extensions.WebPubSub
.Bestätigen und aktualisieren Sie
host.json
's extensionBundle auf Version 4.* oder höher, um Web PubSub-Unterstützung zu erhalten.{ "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[4.*, 5.0.0)" } }
Erstellen Sie eine
index
-Funktion zum Lesen und Hosten einer statischen Webseite für Clients.func new -n index -t HttpTrigger
- Aktualisieren Sie
src/functions/index.js
und kopieren Sie den folgenden Code.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, }; } });
- Aktualisieren Sie
Erstellen Sie eine
negotiate
-Funktion, damit Clients die Dienstverbindungs-URL mit Zugriffstoken abrufen können.func new -n negotiate -t HttpTrigger
Hinweis
In diesem Beispiel wird der Microsoft Entra ID-Header der Benutzeridentität
x-ms-client-principal-name
zum Abrufen vonuserId
verwendet. Dies funktioniert in einer lokalen Funktion nicht. Sie können ihn leer lassen oder auf andere Weise ändern, umuserId
abzurufen oder zu generieren, wenn Sie lokal agieren. Lassen Sie den Client z. B. einen Benutzernamen eingeben und ihn in einer Abfrage wie?user={$username}
übergeben, wenn Sie dienegotiate
-Funktion aufrufen, um die URL für die Verbindung mit dem Dienst zu erhalten. Legen Sie in dernegotiate
-FunktionuserId
auf den Wert{query.user}
fest.- Aktualisieren Sie
src/functions/negotiate
und kopieren Sie den folgenden Code.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')) }; }, });
- Aktualisieren Sie
Erstellen Sie eine
message
-Funktion, um Clientnachrichten über den Dienst zu übertragen.func new -n message -t HttpTrigger
- Aktualisieren Sie
src/functions/message.js
und kopieren Sie den folgenden Code.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", }; } });
- Aktualisieren Sie
Fügen Sie im Stammordner des Projekts die Client-Einzelseite
index.html
hinzu und kopieren Sie den Inhalt.<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>
Erstellen und Bereitstellen der Azure-Funktions-App
Zum Bereitstellen Ihres Funktionscodes in Azure müssen Sie drei Ressourcen erstellen:
- Eine Ressourcengruppe als logischen Container für verwandte Ressourcen.
- Ein Speicherkonto, das verwendet wird, um den Status und andere Informationen zu Ihren Funktionen zu verwalten.
- Eine Funktions-App, die als Umgebung zum Ausführen Ihres Funktionscodes dient. Eine Funktions-App ist Ihrem lokalen Funktionsprojekt zugeordnet und ermöglicht Ihnen das Gruppieren von Funktionen als logische Einheit, um die Verwaltung, Bereitstellung und Freigabe von Ressourcen zu vereinfachen.
Verwenden Sie die folgenden Befehle, um diese Elemente zu erstellen.
Melden Sie sich bei Azure an, falls dies noch nicht geschehen ist:
az login
Erstellen Sie eine Ressourcengruppe oder verwenden Sie einfach die Ressourcengruppe des Azure Web PubSub-Dienstes weiter:
az group create -n WebPubSubFunction -l <REGION>
Erstellen Sie in Ihrer Ressourcengruppe und Region ein universelles Speicherkonto:
az storage account create -n <STORAGE_NAME> -l <REGION> -g WebPubSubFunction
Erstellen Sie die Funktions-App in 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>
Hinweis
Lesen Sie die Dokumentation zu den Azure Functions Runtime-Versionen, um den Parameter
--runtime-version
auf einen unterstützten Wert zu setzen.Stellen Sie das Funktionsprojekts in Azure bereit:
Nachdem Sie Ihre Funktions-App in Azure erfolgreich erstellt haben, können Sie nun Ihr lokales Funktionsprojekt mit dem Befehl func azure functionapp publish bereitstellen.
func azure functionapp publish <FUNCIONAPP_NAME>
Konfigurieren Sie
WebPubSubConnectionString
für die Funktions-App:Suchen Sie zuerst Ihre Web PubSub-Ressource im Azure-Portal, und kopieren Sie die Verbindungszeichenfolge unter Schlüssel. Navigieren Sie anschließend im Azure-Portal unter Einstellungen>Konfiguration zu den Einstellungen für die Funktions-App. Fügen Sie unter Anwendungseinstellungen ein neues Element mit dem Namen und dem Wert
WebPubSubConnectionString
ihrer Web PubSub-Ressourcenverbindungszeichenfolge hinzu.
Konfigurieren des Web PubSub-Diensts Event Handler
In diesem Beispiel verwenden Sie WebPubSubTrigger
, um auf Anforderungen des Diensts für Upstreams zu lauschen. Web PubSub muss also die Endpunktinformationen der Funktion kennen, um die Clientanforderungen senden zu können. Die Azure Functions-App benötigt zudem einen Systemschlüssel für Sicherheit bei erweiterungsspezifischen Webhookmethoden. Nachdem wir im vorherigen Schritt die Funktions-App mit message
-Funktionen bereitgestellt haben, können wir den Systemschlüssel abrufen.
Wechseln Sie zum Azure-Portal, suchen Sie Ihre Funktions-App-Ressource, und wählen Sie >>>>webpubsub_extension
aus. Kopieren Sie den Wert von <APP_KEY>
.
Legen Sie Event Handler
im Azure Web PubSub-Dienst fest. Navigieren Sie im Azure-Portal zu Ihrer Web PubSub-Ressource, und wählen Sie > aus. Fügen Sie eine neue Hubeinstellungszuordnung für die einzelne verwendete Funktion hinzu. Ersetzen Sie die <FUNCTIONAPP_NAME>
und <APP_KEY>
durch Ihre Werte.
- Hub-Name:
simplechat
- URL-Vorlage: https://<FUNCTIONAPP_NAME>.azurewebsites.net/runtime/webhooks/webpubsub?code=<APP_KEY>
- Benutzerereignismuster: *
- Systemereignisse: (bei diesem Beispiel keine Konfiguration nötig)
Konfiguration zum Aktivieren der Clientauthentifizierung
Wechseln Sie zum Azure-Portal. Wählen Sie Ihre Funktions-App-Ressource und dann > aus. Klicken Sie auf Add identity provider
. Legen Sie die Einstellungen für die App Service-Authentifizierung auf Nicht authentifizierten Zugriff zulassen fest, damit Ihre Client-Indexseite von anonymen Benutzern besucht werden kann, bevor sie zur Authentifizierung weitergeleitet werden. Speichern Sie anschließend.
Hier wählen wir Microsoft
als Bezeichner des Anbieters, der x-ms-client-principal-name
als userId
in der negotiate
-Funktion verwendet. Außerdem können Sie andere Identitätsanbieter konfigurieren, indem Sie den Links folgen. Vergessen Sie dabei nicht, den userId
-Wert in der negotiate
-Funktion entsprechend zu aktualisieren.
Testen der Anwendung
Nun können Sie Ihre Seite in Ihrer Funktions-App https://<FUNCTIONAPP_NAME>.azurewebsites.net/api/index
testen. Siehe die Momentaufnahme.
- Klicken Sie auf
login
, um sich zu authentifizieren. - Geben Sie die Nachricht in das Eingabefeld ein, um zu chatten.
In der Nachrichtenfunktion senden wir die Nachricht des Anrufers an alle Clients und geben den Anrufer mit der Nachricht [SYSTEM] ack
zurück. In der Momentaufnahme des Beispielchats sind also die ersten vier Nachrichten vom aktuellen Client und die letzten beiden Nachrichten von einem anderen Client.
Bereinigen von Ressourcen
Wenn Sie diese App nicht mehr benötigen, löschen Sie alle im Rahmen dieser Dokumentation erstellten Ressourcen, damit keine Gebühren anfallen. Gehen Sie dazu wie folgt vor:
Klicken Sie ganz links im Azure-Portal auf Ressourcengruppen und anschließend auf die erstellte Ressourcengruppe. Sie können auch das Suchfeld verwenden, um nach dem Namen der Ressourcengruppe zu suchen.
Wählen im daraufhin angezeigten Fenster die Ressourcengruppe und anschließend die Option Ressourcengruppe löschen aus.
Geben Sie im neuen Fenster den Namen der Ressourcengruppe ein, die Sie löschen möchten, und wählen Sie Löschen aus.
Nächste Schritte
In dieser Schnellstartanleitung haben Sie gelernt, wie Sie eine serverlose Benachrichtigungsanwendung ausführen. Sie können nun damit beginnen, Ihre eigene Anwendung zu erstellen.