Zelfstudie: Een chat-app maken met de Azure Web PubSub-service
In de zelfstudie Berichten publiceren en abonneren leert u de basisprincipes van het publiceren en abonneren van berichten met Azure Web PubSub. In deze zelfstudie leert u het gebeurtenissysteem van Azure Web PubSub en gebruikt u dit om een volledige webtoepassing te bouwen met realtime communicatiefunctionaliteit.
In deze zelfstudie leert u het volgende:
- Een Web PubSub-service-exemplaar maken
- Instellingen voor gebeurtenis-handler configureren voor Azure Web PubSub
- Gebeurtenissen in de app-server afhandelen en een realtime chat-app bouwen
Als u geen Azure-abonnement hebt, kunt u een gratis Azure-account maken voordat u begint.
Vereisten
Gebruik de Bash-omgeving in Azure Cloud Shell. Zie quickstart voor Bash in Azure Cloud Shell voor meer informatie.
Installeer de Azure CLI, indien gewenst, om CLI-referentieopdrachten uit te voeren. Als u in Windows of macOS werkt, kunt u Azure CLI uitvoeren in een Docker-container. Zie De Azure CLI uitvoeren in een Docker-container voor meer informatie.
Als u een lokale installatie gebruikt, meldt u zich aan bij Azure CLI met behulp van de opdracht az login. Volg de stappen die worden weergegeven in de terminal, om het verificatieproces te voltooien. Raadpleeg Aanmelden bij Azure CLI voor aanvullende aanmeldingsopties.
Installeer de Azure CLI-extensie bij het eerste gebruik, wanneer u hierom wordt gevraagd. Raadpleeg Extensies gebruiken met Azure CLI voor meer informatie over extensies.
Voer az version uit om de geïnstalleerde versie en afhankelijke bibliotheken te vinden. Voer az upgrade uit om te upgraden naar de nieuwste versie.
- Voor deze installatie is versie 2.22.0 of hoger van de Azure CLI vereist. Als u Azure Cloud Shell gebruikt, is de nieuwste versie al geïnstalleerd.
Een Azure Web PubSub-exemplaar maken
Een brongroep maken
Een resourcegroep is een logische container waarin Azure-resources worden geïmplementeerd en beheerd. Gebruik de opdracht az group create om een resourcegroep te maken met de naam myResourceGroup
op de eastus
locatie.
az group create --name myResourceGroup --location EastUS
Een Web PubSub-exemplaar maken
Voer az extension add uit om de webpubsub-extensie te installeren of bij te werken naar de huidige versie.
az extension add --upgrade --name webpubsub
Gebruik de azure CLI az webpubsub create command om een Web PubSub te maken in de resourcegroep die u hebt gemaakt. Met de volgende opdracht maakt u een gratis Web PubSub-resource onder resourcegroep myResourceGroup in EastUS:
Belangrijk
Elke Web PubSub-resource moet een unieke naam hebben. Vervang <uw unieke resourcenaam> door de naam van uw Web PubSub in de volgende voorbeelden.
az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1
In de uitvoer van deze opdracht ziet u eigenschappen van de zojuist gemaakte resource. Let op de onderstaande twee eigenschappen:
- Resourcenaam: de naam die u hebt opgegeven voor de
--name
bovenstaande parameter. - hostName: In het voorbeeld is
<your-unique-resource-name>.webpubsub.azure.com/
de hostnaam .
Op dit moment is uw Azure-account de enige die gemachtigd is om bewerkingen uit te voeren op deze nieuwe resource.
ConnectionString ophalen voor toekomstig gebruik
Belangrijk
Onbewerkte verbindingsreeks worden alleen in dit artikel weergegeven voor demonstratiedoeleinden.
Een verbindingsreeks bevat de autorisatiegegevens die nodig zijn voor uw toepassing voor toegang tot de Azure Web PubSub-service. De toegangssleutel in de verbindingsreeks is vergelijkbaar met een hoofdwachtwoord voor uw service. Beveilig uw toegangssleutels altijd in productieomgevingen. Gebruik Azure Key Vault om uw sleutels veilig te beheren en te roteren en uw verbinding te beveiligen.WebPubSubServiceClient
Vermijd het distribueren van toegangssleutels naar andere gebruikers, het coderen ervan of het opslaan van ze ergens in tekst zonder opmaak die toegankelijk is voor anderen. Draai uw sleutels als u denkt dat ze mogelijk zijn aangetast.
Gebruik de azure CLI az webpubsub key command om de ConnectionString van de service op te halen. Vervang de <your-unique-resource-name>
tijdelijke aanduiding door de naam van uw Azure Web PubSub-exemplaar.
az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv
Kopieer de verbindingsreeks om later te gebruiken.
Kopieer de opgehaalde ConnectionString en stel deze in in de omgevingsvariabeleWebPubSubConnectionString
, die later wordt gelezen in de zelfstudie. Vervang <connection-string>
hieronder door de ConnectionString die u hebt opgehaald.
export WebPubSubConnectionString="<connection-string>"
SET WebPubSubConnectionString=<connection-string>
Het project instellen
Vereisten
De toepassing maken
In Azure Web PubSub zijn er twee functies, server en client. Dit concept is vergelijkbaar met de server- en clientrollen in een webtoepassing. Server is verantwoordelijk voor het beheren van de clients, luisteren en reageren op clientberichten. De client is verantwoordelijk voor het verzenden en ontvangen van berichten van de gebruiker van de server en visualiseert deze voor de eindgebruiker.
In deze zelfstudie bouwen we een realtime-webtoepassing voor chats. In een echte webtoepassing omvat de verantwoordelijkheid van de server ook het verifiëren van clients en het leveren van statische webpagina's voor de gebruikersinterface van de toepassing.
We gebruiken ASP.NET Core 8 om de webpagina's te hosten en binnenkomende aanvragen te verwerken.
Laten we eerst een ASP.NET Core-web-app maken in een chatapp
map.
Maak een nieuwe web-app.
mkdir chatapp cd chatapp dotnet new web
Voeg Program.cs toe
app.UseStaticFiles()
ter ondersteuning van het hosten van statische webpagina's.var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseStaticFiles(); app.Run();
Maak een HTML-bestand en sla het op als
wwwroot/index.html
, we gebruiken het voor de gebruikersinterface van de chat-app later.<html> <body> <h1>Azure Web PubSub Chat</h1> </body> </html>
U kunt de server testen door deze uit te voeren dotnet run --urls http://localhost:8080
en te openen http://localhost:8080/index.html
in de browser.
Onderhandelingseindpunt toevoegen
In de zelfstudie Publiceren en abonneren gebruikt de abonnee verbindingsreeks rechtstreeks. In een echte toepassing is het niet veilig om de verbindingsreeks te delen met een client, omdat verbindingsreeks hoge bevoegdheden heeft om bewerkingen voor de service uit te voeren. Laten we nu uw server de verbindingsreeks laten gebruiken en een negotiate
eindpunt beschikbaar maken voor de client om de volledige URL met toegangstoken op te halen. Op deze manier kan de server verificatie-middleware toevoegen vóór het negotiate
eindpunt om onbevoegde toegang te voorkomen.
Installeer eerst de afhankelijkheden.
dotnet add package Microsoft.Azure.WebPubSub.AspNetCore
We gaan nu een /negotiate
eindpunt toevoegen voor de client om het token te genereren.
using Azure.Core;
using Microsoft.Azure.WebPubSub.AspNetCore;
using Microsoft.Azure.WebPubSub.Common;
using Microsoft.Extensions.Primitives;
// Read connection string from environment
var connectionString = Environment.GetEnvironmentVariable("WebPubSubConnectionString");
if (connectionString == null)
{
throw new ArgumentNullException(nameof(connectionString));
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddWebPubSub(o => o.ServiceEndpoint = new WebPubSubServiceEndpoint(connectionString))
.AddWebPubSubServiceClient<Sample_ChatApp>();
var app = builder.Build();
app.UseStaticFiles();
// return the Client Access URL with negotiate endpoint
app.MapGet("/negotiate", (WebPubSubServiceClient<Sample_ChatApp> service, HttpContext context) =>
{
var id = context.Request.Query["id"];
if (StringValues.IsNullOrEmpty(id))
{
context.Response.StatusCode = 400;
return null;
}
return new
{
url = service.GetClientAccessUri(userId: id).AbsoluteUri
};
});
app.Run();
sealed class Sample_ChatApp : WebPubSubHub
{
}
AddWebPubSubServiceClient<THub>()
wordt gebruikt om de serviceclient WebPubSubServiceClient<THub>
te injecteren, waarmee we in de onderhandelingsstap een clientverbindingstoken en in hubmethoden kunnen genereren om service REST API's aan te roepen wanneer hubgebeurtenissen worden geactiveerd. Deze code voor het genereren van tokens is vergelijkbaar met de code die we hebben gebruikt in de zelfstudie voor het publiceren en abonneren van berichten, behalve dat we nog één argument (userId
) doorgeven bij het genereren van het token. Gebruikers-id kan worden gebruikt om de identiteit van de client te identificeren, dus wanneer u een bericht ontvangt waarvan u weet waar het bericht vandaan komt.
De code leest verbindingsreeks uit de omgevingsvariabele WebPubSubConnectionString
die we in de vorige stap hebben ingesteld.
Voer de server opnieuw uit met behulp van dotnet run --urls http://localhost:8080
.
U kunt deze API testen door toegang te krijgen http://localhost:8080/negotiate?id=user1
en u krijgt de volledige URL van de Azure Web PubSub met een toegangstoken.
Gebeurtenissen verwerken
Wanneer er in Azure Web PubSub bepaalde activiteiten plaatsvinden aan de clientzijde (bijvoorbeeld wanneer een client verbinding maakt, verbonden, verbroken of een client berichten verzendt), verzendt de service meldingen naar de server, zodat deze op deze gebeurtenissen kan reageren.
Gebeurtenissen worden geleverd aan de server in de vorm van Webhook. Webhook wordt geleverd en weergegeven door de toepassingsserver en geregistreerd aan de azure Web PubSub-servicezijde. De service roept de webhooks aan wanneer er een gebeurtenis plaatsvindt.
Azure Web PubSub volgt CloudEvents om de gebeurtenisgegevens te beschrijven.
Hieronder verwerken connected
we systeem gebeurtenissen wanneer een client is verbonden en verwerken message
gebruikers gebeurtenissen wanneer een client berichten verzendt om de chat-app te bouwen.
De Web PubSub SDK voor AspNetCore Microsoft.Azure.WebPubSub.AspNetCore
die we in de vorige stap hebben geïnstalleerd, kan ook helpen bij het parseren en verwerken van de CloudEvents-aanvragen.
Voeg eerst gebeurtenis-handlers toe voordat app.Run()
. Geef het eindpuntpad voor de gebeurtenissen op, laten we zeggen /eventhandler
.
app.MapWebPubSubHub<Sample_ChatApp>("/eventhandler/{*path}");
app.Run();
Voeg nu in de klasse Sample_ChatApp
die we in de vorige stap hebben gemaakt, een constructor toe om mee WebPubSubServiceClient<Sample_ChatApp>
te werken dat we gebruiken om de Web PubSub-service aan te roepen. En OnConnectedAsync()
om te reageren wanneer connected
een gebeurtenis wordt geactiveerd, OnMessageReceivedAsync()
om berichten van de client te verwerken.
sealed class Sample_ChatApp : WebPubSubHub
{
private readonly WebPubSubServiceClient<Sample_ChatApp> _serviceClient;
public Sample_ChatApp(WebPubSubServiceClient<Sample_ChatApp> serviceClient)
{
_serviceClient = serviceClient;
}
public override async Task OnConnectedAsync(ConnectedEventRequest request)
{
Console.WriteLine($"[SYSTEM] {request.ConnectionContext.UserId} joined.");
}
public override async ValueTask<UserEventResponse> OnMessageReceivedAsync(UserEventRequest request, CancellationToken cancellationToken)
{
await _serviceClient.SendToAllAsync(RequestContent.Create(
new
{
from = request.ConnectionContext.UserId,
message = request.Data.ToString()
}),
ContentType.ApplicationJson);
return new UserEventResponse();
}
}
In de bovenstaande code gebruiken we de serviceclient om een meldingsbericht in JSON-indeling uit te zenden naar iedereen met wie lid is SendToAllAsync
.
De webpagina bijwerken
Nu gaan we bijwerken index.html
om de logica toe te voegen om verbinding te maken, bericht te verzenden en ontvangen berichten weer te geven op de pagina.
<html>
<body>
<h1>Azure Web PubSub Chat</h1>
<input id="message" placeholder="Type to chat...">
<div id="messages"></div>
<script>
(async function () {
let id = prompt('Please input your user name');
let res = await fetch(`/negotiate?id=${id}`);
let data = await res.json();
let ws = new WebSocket(data.url);
ws.onopen = () => console.log('connected');
let messages = document.querySelector('#messages');
ws.onmessage = event => {
let m = document.createElement('p');
let data = JSON.parse(event.data);
m.innerText = `[${data.type || ''}${data.from || ''}] ${data.message}`;
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>
U kunt in de bovenstaande code zien dat we verbinding maken met behulp van de systeemeigen WebSocket-API in de browser en gebruiken WebSocket.send()
om berichten te verzenden en WebSocket.onmessage
te luisteren naar ontvangen berichten.
U kunt ook client-SDK's gebruiken om verbinding te maken met de service, zodat u automatisch opnieuw verbinding kunt maken, foutafhandeling en meer.
Er is nu nog één stap over om de chat te laten werken. Laten we configureren naar welke gebeurtenissen we belangrijk zijn en waar de gebeurtenissen naartoe moeten worden verzonden in de Web PubSub-service.
De gebeurtenis-handler instellen
We stellen de gebeurtenis-handler in de Web PubSub-service in om de service te laten weten waar de gebeurtenissen naartoe moeten worden verzonden.
Wanneer de webserver lokaal wordt uitgevoerd, hoe de Web PubSub-service de localhost aanroept als deze geen eindpunt heeft dat toegankelijk is voor internet? Er zijn meestal twee manieren. De ene is om localhost openbaar te maken met behulp van een algemeen tunnelhulpprogramma en de andere is om awps-tunnel te gebruiken om het verkeer van de Web PubSub-service via het hulpprogramma naar uw lokale server te tunnelen.
In deze sectie gebruiken we Azure CLI om de gebeurtenis-handlers in te stellen en awps-tunnel te gebruiken om verkeer naar localhost te routeren.
Hubinstellingen configureren
We stellen de URL-sjabloon tunnel
zodanig in dat Web PubSub berichten doorstuurt via de awps-tunnel
tunnelverbinding. Gebeurtenis-handlers kunnen worden ingesteld vanuit de portal of de CLI, zoals beschreven in dit artikel. Hier stellen we deze in via CLI. Omdat we gebeurtenissen in pad /eventhandler
luisteren als de vorige stappenets, stellen we de URL-sjabloon in op tunnel:///eventhandler
.
Gebruik de azure CLI az webpubsub hub create command om de instellingen voor de gebeurtenis-handler voor de Sample_ChatApp
hub te maken.
Belangrijk
Vervang <uw unieke resourcenaam door de naam van uw Web PubSub-resource> die u in de vorige stappen hebt gemaakt.
az webpubsub hub create -n "<your-unique-resource-name>" -g "myResourceGroup" --hub-name "Sample_ChatApp" --event-handler url-template="tunnel:///eventhandler" user-event-pattern="*" system-event="connected"
Awps-tunnel lokaal uitvoeren
Awps-tunnel downloaden en installeren
Het hulpprogramma wordt uitgevoerd op Node.js versie 16 of hoger.
npm install -g @azure/web-pubsub-tunnel-tool
De service verbindingsreeks gebruiken en uitvoeren
export WebPubSubConnectionString="<your connection string>"
awps-tunnel run --hub Sample_ChatApp --upstream http://localhost:8080
De webserver uitvoeren
Nu is alles ingesteld. We voeren de webserver uit en spelen met de chat-app in actie.
Voer nu de server uit met behulp van dotnet run --urls http://localhost:8080
.
Hier vindt u het volledige codevoorbeeld van deze zelfstudie.
http://localhost:8080/index.html
openen. U kunt uw gebruikersnaam invoeren en chatten.
Luie verificatie met connect
gebeurtenis-handler
In de vorige secties laten we zien hoe u een onderhandelingseindpunt gebruikt om de URL van de Web PubSub-service en het JWT-toegangstoken te retourneren voor de clients om verbinding te maken met de Web PubSub-service. In sommige gevallen, bijvoorbeeld edge-apparaten met beperkte resources, kunnen clients de voorkeur geven aan directe verbinding met Web PubSub-resources. In dergelijke gevallen kunt u de gebeurtenishandler configureren voor luie verificatie van de clients, gebruikers-id toewijzen aan de clients, de groepen opgeven waaraan de clients deelnemen zodra ze verbinding maken, de machtigingen configureren connect
die de clients hebben en WebSocket-subprotocol als het WebSocket-antwoord op de client, enzovoort. Details verwijzen naar de specificatie van de gebeurtenis-handler verbinden.
We gaan nu de gebeurtenis-handler gebruiken connect
om hetzelfde te bereiken als wat de sectie onderhandelen doet.
Hubinstellingen bijwerken
Eerst gaan we hubinstellingen bijwerken om ook gebeurtenis-handler op te nemen connect
. We moeten ook anonieme verbinding toestaan, zodat clients zonder JWT-toegangstoken verbinding kunnen maken met de service.
Gebruik de azure CLI az webpubsub hub update command to create the event handler settings for the Sample_ChatApp
hub.
Belangrijk
Vervang <uw unieke resourcenaam door de naam van uw Web PubSub-resource> die u in de vorige stappen hebt gemaakt.
az webpubsub hub update -n "<your-unique-resource-name>" -g "myResourceGroup" --hub-name "Sample_ChatApp" --allow-anonymous true --event-handler url-template="tunnel:///eventhandler" user-event-pattern="*" system-event="connected" system-event="connect"
Upstreamlogica bijwerken om verbindingsbeurtenis af te handelen
Nu gaan we upstreamlogica bijwerken om verbindingsevenementen af te handelen. We kunnen nu ook het onderhandelingseindpunt verwijderen.
Net als wat we doen in het onderhandelingseindpunt als demodoel, lezen we ook de id van de queryparameters. In een verbindingsgebeurtenis blijft de oorspronkelijke clientquery behouden in de hoofdtekst van de aanvraag voor de verbindingsgebeurtenis.
Binnen de klasse Sample_ChatApp
overschrijven OnConnectAsync()
voor het afhandelen connect
van gebeurtenis:
sealed class Sample_ChatApp : WebPubSubHub
{
private readonly WebPubSubServiceClient<Sample_ChatApp> _serviceClient;
public Sample_ChatApp(WebPubSubServiceClient<Sample_ChatApp> serviceClient)
{
_serviceClient = serviceClient;
}
public override ValueTask<ConnectEventResponse> OnConnectAsync(ConnectEventRequest request, CancellationToken cancellationToken)
{
if (request.Query.TryGetValue("id", out var id))
{
return new ValueTask<ConnectEventResponse>(request.CreateResponse(userId: id.FirstOrDefault(), null, null, null));
}
// The SDK catches this exception and returns 401 to the caller
throw new UnauthorizedAccessException("Request missing id");
}
public override async Task OnConnectedAsync(ConnectedEventRequest request)
{
Console.WriteLine($"[SYSTEM] {request.ConnectionContext.UserId} joined.");
}
public override async ValueTask<UserEventResponse> OnMessageReceivedAsync(UserEventRequest request, CancellationToken cancellationToken)
{
await _serviceClient.SendToAllAsync(RequestContent.Create(
new
{
from = request.ConnectionContext.UserId,
message = request.Data.ToString()
}),
ContentType.ApplicationJson);
return new UserEventResponse();
}
}
Index.html bijwerken om rechtstreeks verbinding te maken
Nu gaan we de webpagina bijwerken om rechtstreeks verbinding te maken met de Web PubSub-service. Een ding om te vermelden is dat het Web PubSub-service-eindpunt nu voor demodoeleinden is vastgelegd in de clientcode. Werk de hostnaam <the host name of your service>
van de service in de onderstaande HTML bij met de waarde van uw eigen service. Het kan nog steeds nuttig zijn om de waarde van het Web PubSub-service-eindpunt op te halen van uw server, waardoor u meer flexibiliteit en controle hebt over de locatie waar de client verbinding mee maakt.
<html>
<body>
<h1>Azure Web PubSub Chat</h1>
<input id="message" placeholder="Type to chat...">
<div id="messages"></div>
<script>
(async function () {
// sample host: mock.webpubsub.azure.com
let hostname = "<the host name of your service>";
let id = prompt('Please input your user name');
let ws = new WebSocket(`wss://${hostname}/client/hubs/Sample_ChatApp?id=${id}`);
ws.onopen = () => console.log('connected');
let messages = document.querySelector('#messages');
ws.onmessage = event => {
let m = document.createElement('p');
let data = JSON.parse(event.data);
m.innerText = `[${data.type || ''}${data.from || ''}] ${data.message}`;
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>
De server opnieuw uitvoeren
Voer de server nu opnieuw uit en ga naar de webpagina volgens de instructies daarvoor. Als u bent gestopt awps-tunnel
, voert u ook het tunnelhulpprogramma opnieuw uit.
Volgende stappen
Deze zelfstudie biedt een basisidee van de werking van het gebeurtenissysteem in de Azure Web PubSub-service.
Bekijk andere zelfstudies voor meer informatie over het gebruik van de service.