Självstudie: Publicera och prenumerera på meddelanden mellan WebSocket-klienter med hjälp av subprotocol
I självstudien Skapa en chattapp lärde du dig hur du använder WebSocket-API:er för att skicka och ta emot data med Azure Web PubSub. Du kan se att det inte behövs något protokoll när klienten kommunicerar med tjänsten. Du kan till exempel skicka alla typer av data med , WebSocket.send()
och servern tar emot dem precis som den är. WebSocket-API:er är lätt att använda, men funktionerna är begränsade. Du kan till exempel inte ange händelsenamnet när du skickar händelsen till servern eller publicera meddelandet till andra klienter i stället för att skicka den till servern. I den här självstudien får du lära dig hur du använder subprotocol för att utöka funktionaliteten för klienten.
I den här självstudien lär du dig att:
- Skapa en Web PubSub-tjänstinstans
- Generera den fullständiga URL:en för att upprätta WebSocket-anslutningen
- Publicera meddelanden mellan WebSocket-klienter med hjälp av subprotocol
Om du inte har en Azure-prenumeration skapar du ett kostnadsfritt Azure-konto innan du börjar.
Förutsättningar
Använd Bash-miljön i Azure Cloud Shell. Mer information finns i Snabbstart för Bash i 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 Logga in 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 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
--name
ovan. - 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 Anslut ionString för framtida användning
Viktigt!
En anslutningssträng innehåller den auktoriseringsinformation som krävs för att ditt program ska få åtkomst till Azure Web PubSub-tjänsten. Åtkomstnyckeln i anslutningssträng liknar ett rotlösenord för din tjänst. I produktionsmiljöer bör du alltid vara noga med att skydda dina åtkomstnycklar. Använd Azure Key Vault för att hantera och rotera dina nycklar på ett säkert sätt. 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 tjänstens Anslut ionString. <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 Anslut ionString och använd senare i den här självstudien som värdet <connection_string>
för .
Konfigurera projektet
Förutsättningar
Använda en delprotokol
Klienten kan starta en WebSocket-anslutning med hjälp av en specifik delprotokol. Azure Web PubSub-tjänsten stöder en underprotokol som anropas json.webpubsub.azure.v1
för att ge klienterna möjlighet att publicera/prenumerera direkt via Web PubSub-tjänsten i stället för en tur och retur till den överordnade servern. Mer information om delprotokolen för JSON WebSocket finns i Avsnittet om JSON Web PubSub som stöds i Azure Web PubSub.
Om du använder andra protokollnamn ignoreras de av tjänsten och genomströmningen till servern i anslutningshändelsehanteraren, så att du kan skapa egna protokoll.
Nu ska vi skapa ett webbprogram med hjälp av delprotokolen json.webpubsub.azure.v1
.
Installera beroenden
mkdir logstream cd logstream dotnet new web dotnet add package Microsoft.Extensions.Azure dotnet add package Azure.Messaging.WebPubSub
Skapa serversidan som värd för API:et och webbsidan
/negotiate
.Uppdatera
Program.cs
med koden nedan.- Använd
AddAzureClients
för att lägga till tjänstklienten och läsa anslutningssträng från konfigurationen. - Lägg till
app.UseStaticFiles();
tidigareapp.Run();
för att stödja statiska filer. - Och uppdatera
app.MapGet
för att generera klientåtkomsttoken med/negotiate
begäranden.
using Azure.Messaging.WebPubSub; using Microsoft.Extensions.Azure; var builder = WebApplication.CreateBuilder(args); builder.Services.AddAzureClients(s => { s.AddWebPubSubServiceClient(builder.Configuration["Azure:WebPubSub:ConnectionString"], "stream"); }); var app = builder.Build(); app.UseStaticFiles(); app.MapGet("/negotiate", async context => { var service = context.RequestServices.GetRequiredService<WebPubSubServiceClient>(); var response = new { url = service.GetClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" }).AbsoluteUri }; await context.Response.WriteAsJsonAsync(response); }); app.Run();
- Använd
Skapa webbsidan
Skapa en HTML-sida med innehållet nedan och spara den som
wwwroot/index.html
:<html> <body> <div id="output"></div> <script> (async function () { let res = await fetch('/negotiate') let data = await res.json(); let ws = new WebSocket(data.url, 'json.webpubsub.azure.v1'); ws.onopen = () => { console.log('connected'); }; let output = document.querySelector('#output'); ws.onmessage = event => { let d = document.createElement('p'); d.innerText = event.data; output.appendChild(d); }; })(); </script> </body> </html>
Koden ovan ansluter till tjänsten och skriver ut alla meddelanden som tas emot på sidan. Den viktigaste ändringen är att vi anger delprotokolen när du skapar WebSocket-anslutningen.
Kör servern
Vi använder Secret Manager-verktyget för .NET Core för att ange anslutningssträng. Kör kommandot nedan och ersätt
<connection_string>
med det som hämtades i föregående steg och öppna http://localhost:5000/index.html i webbläsaren:dotnet user-secrets init dotnet user-secrets set Azure:WebPubSub:ConnectionString "<connection-string>" dotnet run
Om du använder Chrome kan du trycka på F12 eller högerklicka på ->Inspect ->Developer Tools och välja fliken Nätverk . Läs in webbsidan så ser du att WebSocket-anslutningen har upprättats. Välj för att inspektera WebSocket-anslutningen. Du kan se att händelsemeddelandet nedan
connected
tas emot i klienten. Du kan se att du kan hämta denconnectionId
genererade för den här klienten.{"type":"system","event":"connected","userId":null,"connectionId":"<the_connection_id>"}
Du kan se att med hjälp av subprotocol kan du få några metadata för anslutningen när anslutningen är connected
.
Klienten tar nu emot ett JSON-meddelande i stället för en oformaterad text. JSON-meddelandet innehåller mer information, till exempel typ och källa för meddelandet. Du kan därför använda den här informationen för att bearbeta meddelandet mer (till exempel visa meddelandet i ett annat format om det är från en annan källa), som du kan hitta i senare avsnitt.
Publicera meddelanden från klienten
I självstudiekursen Skapa en chattapp utlöser tjänsten en användarhändelse på serversidan när klienten skickar ett meddelande via WebSocket-anslutning till Web PubSub-tjänsten. Med subprotocol har klienten fler funktioner genom att skicka ett JSON-meddelande. Du kan till exempel publicera meddelanden direkt från klienten via Web PubSub-tjänsten till andra klienter.
Detta är användbart om du vill strömma en stor mängd data till andra klienter i realtid. Nu ska vi använda den här funktionen för att skapa ett loggströmningsprogram som kan strömma konsolloggar till webbläsaren i realtid.
Skapa strömningsprogrammet
Skapa ett
stream
program:mkdir stream cd stream dotnet new console
Uppdatera
Program.cs
med följande innehåll:using System; using System.Net.Http; using System.Net.WebSockets; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace stream { class Program { private static readonly HttpClient http = new HttpClient(); static async Task Main(string[] args) { // Get client url from remote var stream = await http.GetStreamAsync("http://localhost:5000/negotiate"); var url = (await JsonSerializer.DeserializeAsync<ClientToken>(stream)).url; var client = new ClientWebSocket(); client.Options.AddSubProtocol("json.webpubsub.azure.v1"); await client.ConnectAsync(new Uri(url), default); Console.WriteLine("Connected."); var streaming = Console.ReadLine(); while (streaming != null) { if (!string.IsNullOrEmpty(streaming)) { var message = JsonSerializer.Serialize(new { type = "sendToGroup", group = "stream", data = streaming + Environment.NewLine, }); Console.WriteLine("Sending " + message); await client.SendAsync(Encoding.UTF8.GetBytes(message), WebSocketMessageType.Text, true, default); } streaming = Console.ReadLine(); } await client.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default); } private sealed class ClientToken { public string url { get; set; } } } }
Du kan se att det finns en ny konceptgrupp här. Grupp är ett logiskt begrepp i en hubb där du kan publicera meddelanden till en grupp med anslutningar. I en hubb kan du ha flera grupper och en klient kan prenumerera på flera grupper samtidigt. När du använder subprotocol kan du bara publicera till en grupp i stället för att sända till hela hubben. Mer information om villkoren finns i de grundläggande begreppen.
Eftersom vi använder gruppen här måste vi också uppdatera webbsidan
index.html
för att ansluta till gruppen när WebSocket-anslutningen upprättas iws.onopen
återanropet.let ackId = 0; ws.onopen = () => { console.log('connected'); ws.send(JSON.stringify({ type: 'joinGroup', group: 'stream', ackId: ++ackId })); };
Du kan se att klienten ansluter till gruppen genom att skicka ett meddelande av
joinGroup
typen .Uppdatera
ws.onmessage
även motringningslogik något för att parsa JSON-svaret och skriva ut meddelandena endast frånstream
gruppen så att det fungerar som live stream-skrivare.ws.onmessage = event => { let message = JSON.parse(event.data); if (message.type === 'message' && message.group === 'stream') { let d = document.createElement('span'); d.innerText = message.data; output.appendChild(d); window.scrollTo(0, document.body.scrollHeight); } };
Av säkerhetsskäl kan en klient som standard inte publicera eller prenumerera på en grupp på egen hand. Så du har märkt att vi ställer in
roles
på klienten när du genererar token:Ange när
GenerateClientAccessUri
iroles
Startup.cs
som nedan:service.GenerateClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" })
Slutligen även tillämpa lite stil på
index.html
så att det visas fint.<html> <head> <style> #output { white-space: pre; font-family: monospace; } </style> </head>
Kör nu koden nedan och skriv text och de visas i webbläsaren i realtid:
ls -R | dotnet run
# Or call `dir /s /b | dotnet run` when you are using CMD under Windows
Eller så gör du det långsammare så att du kan se att data strömmas till webbläsaren i realtid:
for i in $(ls -R); do echo $i; sleep 0.1; done | dotnet run
Det fullständiga kodexemplet i den här självstudien finns här.
Nästa steg
I den här självstudien får du en grundläggande uppfattning om hur du ansluter till Web PubSub-tjänsten och hur du publicerar meddelanden till anslutna klienter med hjälp av subprotokol.
Kontrollera andra självstudier för att ytterligare undersöka hur du använder tjänsten.