Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I Självstudien Publicera och prenumerera på meddelanden får du lära dig grunderna för att publicera och prenumerera på meddelanden med Azure Web PubSub. I den här självstudien lär du dig händelsesystemet för Azure Web PubSub och använder det för att skapa ett komplett webbprogram med kommunikationsfunktioner i realtid.
I den här självstudien lär du dig att:
- Skapa en Web PubSub-tjänstinstans
- Konfigurera händelsehanterarinställningar för Azure Web PubSub
- Hantera händelser på appservern och skapa en chattapp i realtid
Om du inte har något Azure-konto skapar du ett kostnadsfritt konto innan du börjar.
Förutsättningar
Använd Bash-miljön i Azure Cloud Shell. Mer information finns i Kom igång med Azure Cloud Shell.
Om du föredrar att köra CLI-referenskommandon lokalt installerar du Azure CLI. Om du kör i Windows eller macOS kan du köra Azure CLI i en Docker-container. Mer information finns i Så här kör du Azure CLI i en Docker-container.
Om du använder en lokal installation loggar du in på Azure CLI med hjälp av kommandot az login. Slutför autentiseringsprocessen genom att följa stegen som visas i terminalen. Andra inloggningsalternativ finns i Autentisera till Azure med Azure CLI.
När du uppmanas att installera Azure CLI-tillägget vid första användningen. Mer information om tillägg finns i Använda och hantera tillägg med Azure CLI.
Kör az version om du vill hitta versionen och de beroende bibliotek som är installerade. Om du vill uppgradera till den senaste versionen kör du az upgrade.
- Den här konfigurationen kräver version 2.22.0 eller senare av Azure CLI. Om du använder Azure Cloud Shell är den senaste versionen redan installerad.
Skapa en Azure Web PubSub-instans
Skapa en resursgrupp
En resursgrupp är en logisk container där Azure-resurser distribueras och hanteras.
Använd kommandot az group create för att skapa en resursgrupp med namnet myResourceGroup på eastus platsen.
az group create --name myResourceGroup --location EastUS
Skapa en Web PubSub-instans
Kör az extension add för att installera eller uppgradera webpubsub-tillägget till den aktuella versionen.
az extension add --upgrade --name webpubsub
Använd kommandot Azure CLI az webpubsub create för att skapa en Web PubSub i resursgruppen som du har skapat. Följande kommando skapar en Free Web PubSub-resurs under resursgruppen myResourceGroup i EastUS:
Viktigt!
Varje Web PubSub-resurs måste ha ett unikt namn. Ersätt <ditt unika resursnamn> med namnet på din Web PubSub i följande exempel.
az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1
Utdata från det här kommandot visar egenskaperna för den nyligen skapade resursen. Anteckna de två egenskaperna som visas nedan:
-
Resursnamn: Det namn som du angav i parametern
--nameovan. -
hostName: I exemplet är
<your-unique-resource-name>.webpubsub.azure.com/värdnamnet .
I det här läget är ditt Azure-konto det enda som har behörighet att utföra åtgärder på den nya resursen.
Hämta ConnectionString för framtida användning
Viktigt!
Råa anslutningssträng visas endast i den här artikeln i demonstrationssyfte.
En reťazec pripojenia inkluderar den auktoriseringsinformation som din applikation behöver för att få tillgång till Azure Web PubSub-tjänsten. Accessnyckeln i reťazec pripojenia fungerar som ett root-lösenord för din tjänst. Skydda alltid dina åtkomstnycklar i produktionsmiljöer. Använd Azure Key Vault för att hantera och rotera dina nycklar på ett säkert sätt och skydda anslutningen med WebPubSubServiceClient.
Undvik att distribuera åtkomstnycklar till andra användare, hårdkoda dem eller spara dem var som helst i oformaterad text som är tillgänglig för andra. Rotera dina nycklar om du tror att de har komprometterats.
Använd kommandot Azure CLI az webpubsub key för att hämta ConnectionString för tjänsten.
<your-unique-resource-name> Ersätt platshållaren med namnet på din Azure Web PubSub-instans.
az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv
Kopiera anslutningssträng som ska användas senare.
Kopiera den hämtade ConnectionString och ställ in den i miljövariabeln WebPubSubConnectionString, som självstudien senare läser. Ersätt <connection-string> nedan med den ConnectionString som du hämtade.
export WebPubSubConnectionString="<connection-string>"
SET WebPubSubConnectionString=<connection-string>
Konfigurera projektet
Förutsättningar
Skapa programmet
I Azure Web PubSub finns det två roller, server och klient. Det här konceptet liknar server- och klientrollerna i ett webbprogram. Servern ansvarar för att hantera klienter, lyssna och svara på klientmeddelanden. Klienten ansvarar för att skicka och ta emot användarens meddelanden från servern och visualisera dem för slutanvändare.
I den här handledningen bygger vi en webbapplikation för realtidschatt. I ett riktigt webbprogram omfattar serverns ansvar även att autentisera klienter och hantera statiska webbsidor för programmets användargränssnitt.
Vi använder ASP.NET Core 8 som värd för webbsidorna och hanterar inkommande begäranden.
Först ska vi skapa en ASP.NET Core-webbapp i en chatapp mapp.
Skapa en ny webbapp.
mkdir chatapp cd chatapp dotnet new webLägg till
app.UseStaticFiles()Program.cs för att stödja värdskap för statiska webbsidor.var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseStaticFiles(); app.Run();Skapa en HTML-fil och spara den som
wwwroot/index.html, vi använder den för chattappens användargränssnitt senare.<html> <body> <h1>Azure Web PubSub Chat</h1> </body> </html>
Du kan testa servern genom att köra dotnet run --urls http://localhost:8080 och komma åt http://localhost:8080/index.html den i webbläsaren.
Lägg till förhandlingsslutpunkt
I självstudien Publicera och prenumerera på meddelanden använder prenumeranten anslutningssträngen direkt. I ett verkligt program är det inte säkert att dela anslutningssträng med någon klient, eftersom anslutningssträng har hög behörighet att utföra alla åtgärder i tjänsten. Nu ska vi låta servern använda anslutningssträngen och exponera en negotiate-ändpunkt så att klienten kan hämta den fullständiga URL:en med åtkomsttoken. På så sätt kan servern lägga till autentiseringsmellanprogram före negotiate slutpunkten för att förhindra obehörig åtkomst.
Installera först beroendena.
dotnet add package Microsoft.Azure.WebPubSub.AspNetCore
Nu lägger vi till en /negotiate endpoint som klienten kan anropa för att generera tokenen.
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>() används för att mata in tjänstklienten WebPubSubServiceClient<THub>, med vilken vi kan använda i förhandlingssteget för att generera klientanslutningstoken och i hubbmetoder för att anropa tjänstens REST-API:er när hubbhändelser utlöses. Den här koden för att generera token liknar den vi använde i självstudien om att publicera och prenumerera på meddelanden, förutom att vi skickar med ett argument till (userId) när vi genererar token. Användar-ID kan användas för att identifiera klientens identitet, så när du får ett meddelande vet du var meddelandet kommer ifrån.
Koden läser anslutningssträng från miljövariabeln WebPubSubConnectionString som vi angav i föregående steg.
Kör servern igen med .dotnet run --urls http://localhost:8080
Du kan testa det här API:et genom att http://localhost:8080/negotiate?id=user1 komma åt och det ger dig den fullständiga URL:en för Azure Web PubSub med en åtkomsttoken.
Hantera händelser
När det finns vissa aktiviteter på klientsidan i Azure Web PubSub (till exempel en klient ansluter, ansluter, kopplar från eller en klient skickar meddelanden) skickar tjänsten meddelanden till servern så att den kan reagera på dessa händelser.
Händelser levereras till servern i form av Webhook. Webhook hanteras och exponeras av programservern och registreras på Azure Web PubSub-tjänstsidan. Tjänsten utlöser webhooks när en händelse inträffar.
Azure Web PubSub följer CloudEvents för att beskriva händelsedata.
Nedan hanterar connected vi systemhändelser när en klient är ansluten och hanterar message användarhändelser när en klient skickar meddelanden för att skapa chattappen.
Web PubSub SDK för AspNetCore Microsoft.Azure.WebPubSub.AspNetCore som vi installerade i föregående steg kan också hjälpa dig att parsa och bearbeta CloudEvents-begäranden.
Lägg först till händelsehanterare före app.Run(). Ange slutpunktssökvägen för händelserna, låt oss säga /eventhandler.
app.MapWebPubSubHub<Sample_ChatApp>("/eventhandler/{*path}");
app.Run();
I den klass Sample_ChatApp som vi skapade i föregående steg lägger du nu till en konstruktor för att arbeta med WebPubSubServiceClient<Sample_ChatApp>, som vi använder för att anropa Web PubSub-tjänsten. Och OnConnectedAsync() för att svara när connected händelsen utlöses, OnMessageReceivedAsync() för att hantera meddelanden från klienten.
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();
}
}
I koden ovan använder vi tjänstklienten för att sända ett meddelande i JSON-format till alla som är anslutna till SendToAllAsync.
Uppdatera webbsidan
Nu ska vi uppdatera index.html för att lägga till logiken för att ansluta, skicka meddelande och visa mottagna meddelanden på sidan.
<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>
Du kan se i koden ovan att vi ansluter använda det interna WebSocket-API:et i webbläsaren och använda WebSocket.send() för att skicka meddelanden och WebSocket.onmessage lyssna på mottagna meddelanden.
Du kan också använda klient-SDK:er för att ansluta till tjänsten, vilket ger dig automatisk återanslutning, felhantering med mera.
Det finns nu ett steg kvar för chatten att fungera. Nu ska vi konfigurera vilka händelser vi bryr oss om och var händelserna ska skickas till i tjänsten Web PubSub.
Konfigurera händelsehanteraren
Vi ställer in händelsehanteraren i Web PubSub-tjänsten för att tala om för tjänsten var händelserna ska skickas.
Hur anropar Web PubSub-tjänsten localhost om den inte har någon internettillgänglig slutpunkt när webbservern körs lokalt? Det finns vanligtvis två sätt. Det ena är att exponera localhost publikt med hjälp av ett allmänt tunnelverktyg, och det andra är att använda awps-tunnel för att tunnelera trafiken från Web PubSub-tjänsten genom verktyget till din lokala server.
I det här avsnittet använder vi Azure CLI för att ange händelsehanterare och använda awps-tunnel för att dirigera trafik till localhost.
Konfigurera hubbinställningar
Vi anger att URL-mallen ska använda tunnel schemat så att Web PubSub dirigerar meddelanden via tunnelanslutningen awps-tunnel. Händelsehanterare kan ställas in från antingen portalen eller CLI enligt beskrivningen i den här artikeln, här anger vi det via CLI. Eftersom vi lyssnar efter händelser i sökvägen /eventhandler, som anges i föregående steg, ställer vi in URL-mallen till tunnel:///eventhandler.
Använd azure CLI az webpubsub hub create-kommandot för att skapa händelsehanterarinställningarna för Sample_ChatApp hubben.
Viktigt!
Ersätt <ditt unika resursnamn> med namnet på din Web PubSub-resurs som skapades från föregående steg.
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"
Kör awps-tunnel lokalt
Ladda ned och installera awps-tunnel
Verktyget körs på Node.js version 16 eller senare.
npm install -g @azure/web-pubsub-tunnel-tool
Använd tjänstens anslutningssträng och kör
export WebPubSubConnectionString="<your connection string>"
awps-tunnel run --hub Sample_ChatApp --upstream http://localhost:8080
Kör webbservern
Nu är allt klart. Nu ska vi köra webbservern och leka med chattappen i praktiken.
Kör nu servern med .dotnet run --urls http://localhost:8080
Det fullständiga kodexemplet i den här självstudien finns här.
Öppna http://localhost:8080/index.html. Du kan ange ditt användarnamn och börja chatta.
Lazy Auth med connect-händelsehanterare
I föregående avsnitt visar vi hur du använder förhandlingsslutpunkten för att returnera url:en för Web PubSub-tjänsten och JWT-åtkomsttoken för klienterna för att ansluta till Web PubSub-tjänsten. I vissa fall, till exempel gränsenheter som har begränsade resurser, kan klienter föredra direktanslutning till Web PubSub-resurser. I sådana fall kan du konfigurera connect händelsehanteraren så att klienterna autentiseras vid behov, tilldela klienterna användar-ID:n, ange vilka grupper klienterna ska gå med i när de har anslutit, konfigurera vilka behörigheter klienterna ska ha samt ange WebSocket-delprotokoll som WebSocket-svar till klienten. Mer information finns i specifikationen för anslutningshändelsehanteraren.
Nu ska vi använda connect-händelsehanteraren för att uppnå något liknande det som avsnittet negotiate gör.
Uppdatera inställningar för hubben
Först ska vi uppdatera hubbinställningarna för att även inkludera connect händelsehanterare. Vi måste också tillåta anonym anslutning så att klienter utan JWT-åtkomsttoken kan ansluta till tjänsten.
Använd azure CLI az webpubsub hub update-kommandot för att skapa händelsehanterarinställningarna för Sample_ChatApp hubben.
Viktigt!
Ersätt <ditt unika resursnamn> med namnet på din Web PubSub-resurs som skapades från föregående steg.
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"
Uppdatera uppströmslogik för att hantera anslutningshändelse
Nu ska vi uppdatera den överordnade logiken för att hantera anslutningshändelsen. Vi kan också ta bort förhandlingsslutpunkten nu.
På samma sätt som vi gör i negotiate-endpointen läser vi också id från frågeparametrarna i demonstrationssyfte. I connect-händelsen bevaras den ursprungliga klientfrågan i brödtexten för anslutningshändelsebegäran.
I klassen Sample_ChatAppåsidosätter du OnConnectAsync() för att hantera connect händelsen:
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();
}
}
Uppdatera index.html för direktanslutning
Nu ska vi uppdatera webbsidan för att direktansluta till Web PubSub-tjänsten. En sak att nämna är att slutpunkten för Web PubSub-tjänsten nu är hårdkodad i klientkoden för demonstrationssyfte. Uppdatera tjänstens värdnamn <the host name of your service> i HTML-koden nedan med värdet från din egen tjänst. Det kan fortfarande vara användbart att hämta slutpunktsvärdet för Web PubSub-tjänsten från servern. Det ger dig mer flexibilitet och kontrollbarhet till den punkt där klienten ansluter till.
<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>
Kör servern igen
Kör nu servern igen och besök webbsidan enligt anvisningarna innan. Om du har stoppat awps-tunnel, kör även tunnelverktyget igen.
Nästa steg
I den här självstudien får du en grundläggande uppfattning om hur händelsesystemet fungerar i Azure Web PubSub-tjänsten.
Se andra guider för att lära dig mer om hur tjänsten används.