Dela via


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

  • 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 myResourceGroupeastus 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 .

  1. Installera beroenden

    mkdir logstream
    cd logstream
    dotnet new web
    dotnet add package Microsoft.Extensions.Azure
    dotnet add package Azure.Messaging.WebPubSub
    
  2. 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(); tidigare app.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();
    
  3. 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.

  4. 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 den connectionId 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.

  1. 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.

  2. 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 i ws.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 .

  3. Uppdatera ws.onmessage även motringningslogik något för att parsa JSON-svaret och skriva ut meddelandena endast från stream 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);
      }
    };
    
  4. 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 i roles Startup.cs som nedan:

    service.GenerateClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" })
    
  5. 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.