Självstudie: Skapa en serverlös chattapp i realtid med Azure Functions och Azure Web PubSub-tjänsten
Tjänsten Azure Web PubSub hjälper dig att enkelt skapa webbprogram för meddelanden i realtid med hjälp av WebSockets och mönstret publicera-prenumerera. Azure Functions är en serverlös plattform som gör att du kan köra din kod utan att behöva hantera någon infrastruktur. I den här självstudien får du lära dig hur du använder Tjänsten Azure Web PubSub och Azure Functions för att skapa ett serverlöst program med meddelanden i realtid och mönstret publicera-prenumerera.
I den här självstudien lär du dig att:
- Skapa en serverlös chattapp i realtid
- Arbeta med Web PubSub-funktionsutlösarbindningar och utdatabindningar
- Distribuera funktionen till Azure-funktionsappen
- Konfigurera Azure-autentisering
- Konfigurera Web PubSub Event Handler för att dirigera händelser och meddelanden till programmet
Förutsättningar
En kodredigerare, till exempel Visual Studio Code
Node.js version 18.x eller senare.
Kommentar
Mer information om vilka versioner av Node.js som stöds finns i dokumentationen om Azure Functions-körningsversioner.
Azure Functions Core Tools (v4 eller senare rekommenderas) för att köra Azure Function-appar lokalt och distribuera till Azure.
Azure CLI för att hantera Azure-resurser.
Om du inte har en Azure-prenumeration skapar du ett kostnadsfritt Azure-konto innan du börjar.
Logga in på Azure
Logga in på Azure Portal på https://portal.azure.com/ med ditt Azure-konto.
Skapa en Azure Web PubSub-tjänstinstans
Ditt program ansluter till en Web PubSub-tjänstinstans i Azure.
Välj knappen Nytt högst upp till vänster i Azure-portalen. På skärmen Nytt skriver du Web PubSub i sökrutan och trycker på Retur. (Du kan också söka i Azure Web PubSub från
Web
kategorin.)Välj Web PubSub i sökresultatet och välj sedan Skapa.
Ange följande inställningar.
Inställning Föreslaget värde beskrivning Resursnamn Globalt unikt namn Det globalt unika namn som identifierar din nya Web PubSub-tjänstinstans. Giltiga tecken är a-z
,A-Z
,0-9
och-
.Abonnemang Din prenumeration Den Azure-prenumeration under vilken den här nya Web PubSub-tjänstinstansen skapas. Resursgrupp myResourceGroup Namn på den nya resursgrupp där du vill skapa din Web PubSub-tjänstinstans. Plats Västra USA Välj en region nära dig. Prisnivå Kostnadsfri Du kan prova tjänsten Azure Web PubSub kostnadsfritt. Läs mer om prisnivåer för Azure Web PubSub-tjänsten Antal enheter - Antal enheter anger hur många anslutningar din Web PubSub-tjänstinstans kan acceptera. Varje enhet stöder högst 1 000 samtidiga anslutningar. Det kan bara konfigureras på Standard-nivån. Välj Skapa för att börja distribuera instansen av Web PubSub-tjänsten.
Skapa funktionerna
Kontrollera att du har Azure Functions Core Tools installerat. Skapa sedan en tom katalog för projektet. Kör kommandot under den här arbetskatalogen.
func init --worker-runtime javascript --model V4
Installera
Microsoft.Azure.WebJobs.Extensions.WebPubSub
.Bekräfta och uppdatera
host.json
tilläggetBundle till version 4.* eller senare för att få support för Web PubSub.{ "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[4.*, 5.0.0)" } }
Skapa en
index
funktion för att läsa och vara värd för en statisk webbsida för klienter.func new -n index -t HttpTrigger
- Uppdatera
src/functions/index.js
och kopiera följande koder.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, }; } });
- Uppdatera
Skapa en
negotiate
funktion som hjälper klienter att hämta url:en för tjänstanslutning med åtkomsttoken.func new -n negotiate -t HttpTrigger
Kommentar
I det här exemplet använder vi användaridentitetshuvudet
x-ms-client-principal-name
för Microsoft Entra-ID för att hämtauserId
. Och detta fungerar inte i en lokal funktion. Du kan göra den tom eller ändra till andra sätt att hämta eller genererauserId
när du spelar lokalt. Låt till exempel klienten skriva ett användarnamn och skicka det i fråga som?user={$username}
när anropsfunktionennegotiate
för att hämta url för tjänstanslutning. Och inegotiate
funktionen anger duuserId
med värdet{query.user}
.- Uppdatera
src/functions/negotiate
och kopiera följande koder.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')) }; }, });
- Uppdatera
Skapa en
message
funktion för att sända klientmeddelanden via tjänsten.func new -n message -t HttpTrigger
- Uppdatera
src/functions/message.js
och kopiera följande koder.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", }; } });
- Uppdatera
Lägg till klientens enstaka sida
index.html
i projektets rotmapp och kopiera innehåll.<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>
Skapa och distribuera Azure-funktionsappen
Innan du kan distribuera funktionskoden till Azure måste du skapa tre resurser:
- En resursgrupp, som är en logisk container för relaterade resurser.
- Ett lagringskonto som används för att underhålla tillstånd och annan information om dina funktioner.
- En funktionsapp som tillhandahåller miljön för att köra funktionskoden. En funktionsapp mappar till ditt lokala funktionsprojekt och låter dig gruppera funktioner som en logisk enhet för enklare hantering, distribution och delning av resurser.
Använd följande kommandon för att skapa dessa objekt.
Om du inte redan har gjort det loggar du in på Azure:
az login
Skapa en resursgrupp eller så kan du hoppa över genom att återanvända en av Azure Web PubSub-tjänsten:
az group create -n WebPubSubFunction -l <REGION>
Skapa ett allmänt lagringskonto i din resursgrupp och region:
az storage account create -n <STORAGE_NAME> -l <REGION> -g WebPubSubFunction
Skapa funktionsappen i 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>
Kommentar
Kontrollera dokumentationen för Azure Functions-körningsversioner för att ange
--runtime-version
parametern till det värde som stöds.Distribuera funktionsprojektet till Azure:
När du har skapat funktionsappen i Azure är du nu redo att distribuera ditt lokala funktionsprojekt med hjälp av publiceringskommandot func azure functionapp .
func azure functionapp publish <FUNCIONAPP_NAME>
WebPubSubConnectionString
Konfigurera för funktionsappen:Leta först upp din Web PubSub-resurs från Azure Portal och kopiera ut niska veze under Nycklar. Navigera sedan till Funktionsappsinställningar i Azure-portalen –> Inställningar –> Konfiguration. Och lägg till ett nytt objekt under Programinställningar, med namnet lika
WebPubSubConnectionString
med och värdet är din Web PubSub-resurs niska veze.
Konfigurera tjänsten Web PubSub Event Handler
I det här exemplet använder WebPubSubTrigger
vi för att lyssna på uppströmsbegäranden i tjänsten. Web PubSub behöver därför känna till funktionens slutpunktsinformation för att kunna skicka målklientbegäranden. Och Azure-funktionsappen kräver en systemnyckel för säkerhet för tilläggsspecifika webhookmetoder. I föregående steg när vi har distribuerat funktionsappen med message
funktioner kan vi hämta systemnyckeln.
Gå till Azure-portalen –> Hitta funktionsappresursen ->Appnycklar ->Systemnycklar ->webpubsub_extension
. Kopiera ut värdet som <APP_KEY>
.
Ange Event Handler
i Azure Web PubSub-tjänsten. Gå till Azure-portalen –> Hitta din Web PubSub-resurs –> Inställningar. Lägg till en ny hubbinställningsmappning till den funktion som används. <FUNCTIONAPP_NAME>
Ersätt och <APP_KEY>
till din.
- Hubbnamn:
simplechat
- URL-mall: https://< FUNCTIONAPP_NAME.azurewebsites.net/runtime/webhooks/webpubsub?code>=<APP_KEY>
- Användarhändelsemönster: *
- Systemhändelser: -(Du behöver inte konfigurera i det här exemplet)
Konfigurera för att aktivera klientautentisering
Gå till Azure-portalen –> Hitta funktionsappresursen ->Autentisering. Klicka på Add identity provider
. Ställ in autentiseringsinställningar för App Service på Tillåt oautentiserad åtkomst, så att klientindexsidan kan besökas av anonyma användare innan du omdirigerar till autentisering. Sedan spara.
Här väljer Microsoft
vi som identifierare, som använder x-ms-client-principal-name
som userId
i negotiate
funktionen. Dessutom kan du konfigurera andra identitetsprovidrar efter länkarna och glöm inte att uppdatera userId
värdet i funktionen i negotiate
enlighet med detta.
Testa programmet
Nu kan du testa sidan från funktionsappen: https://<FUNCTIONAPP_NAME>.azurewebsites.net/api/index
. Se ögonblicksbild.
- Klicka om du
login
vill autentisera dig själv. - Skriv meddelandet i indatarutan för att chatta.
I meddelandefunktionen sänder vi uppringarens meddelande till alla klienter och returnerar anroparen med meddelandet [SYSTEM] ack
. Så vi kan veta i exempel på chattögonblicksbild att de första fyra meddelandena kommer från den aktuella klienten och att de två sista meddelandena kommer från en annan klient.
Rensa resurser
Om du inte kommer att fortsätta att använda den här appen tar du bort alla resurser som skapats av det här dokumentet med följande steg så att du inte debiteras några avgifter:
Välj Resursgrupper i Azure Portal längst till vänster och välj sedan den resursgrupp du skapat. Du kan använda sökrutan för att hitta resursgruppen med dess namn i stället.
I fönstret som öppnas väljer du resursgruppen och väljer sedan Ta bort resursgrupp.
I det nya fönstret skriver du namnet på resursgruppen som ska tas bort och väljer sedan Ta bort.
Nästa steg
I den här snabbstarten har du lärt dig hur du kör ett serverlöst chattprogram. Nu kan du börja skapa ett eget program.