Kurz: Publikování a přihlášení k odběru zpráv mezi klienty WebSocket pomocí subprotocolu

V kurzu k vytvoření chatovací aplikace jste zjistili, jak pomocí rozhraní WebSocket API odesílat a přijímat data pomocí azure Web PubSub. Když klient komunikuje se službou, uvidíte, že není potřeba žádný protokol. Můžete například odeslat libovolný typ dat pomocí WebSocket.send()a server je přijme stejně, jako je. Proces rozhraní API protokolu WebSocket se snadno používá, ale funkce jsou omezené. Například při odesílání události na server nemůžete zadat název události nebo publikovat zprávu jiným klientům místo odeslání na server. V tomto kurzu se naučíte používat subprotocol k rozšíření funkcí klienta.

V tomto kurzu se naučíte:

  • Vytvoření instance služby Web PubSub
  • Vygenerování úplné adresy URL pro navázání připojení WebSocket
  • Publikování zpráv mezi klienty Protokolu WebSocket pomocí subprotocolu

Pokud nemáte účet Azure, vytvořte si bezplatný účet před tím, než začnete.

Požadavky

  • Tato instalace vyžaduje verzi 2.22.0 nebo vyšší rozhraní příkazového řádku Azure CLI. Pokud používáte Azure Cloud Shell, je už nainstalovaná nejnovější verze.

Důležité

Připojovací řetězce v původní podobě se v tomto článku uvádějí pouze pro demonstrační účely.

připojovací řetězec obsahuje autorizační informace, které vaše aplikace potřebuje k přístupu ke službě Azure Web PubSub. Přístupový klíč v připojovací řetězec funguje jako root heslo pro vaši službu. V produkčních prostředích vždy chraňte přístupové klíče. Pomocí služby Azure Key Vault můžete bezpečně spravovat a obměňovat klíče a zabezpečit připojení WebPubSubServiceClient.

Vyhněte se distribuci přístupových klíčů ostatním uživatelům, jejich pevnému kódování nebo jejich uložení kdekoli ve formátu prostého textu, který je přístupný ostatním uživatelům. Otočte klíče, pokud se domníváte, že mohly být ohroženy.

Vytvoření instance Azure Web PubSub

Vytvoření skupiny zdrojů

Skupina prostředků je logický kontejner, ve kterém se nasazují a spravují prostředky Azure. Pomocí příkazu az group create vytvořte skupinu prostředků s názvem myResourceGroup v umístění eastus.

az group create --name myResourceGroup --location EastUS

Vytvoření instance Web PubSub

Spusťte příkaz az extension add, abyste nainstalovali nebo aktualizovali rozšíření webpubsub na aktuální verzi.

az extension add --upgrade --name webpubsub

Pomocí příkazu Azure CLI az webpubsub create vytvořte službu Web PubSub ve vámi vytvořené skupině prostředků. Následující příkaz vytvoří prostředek Free Web PubSub ve skupině prostředků myResourceGroup v eastUS:

Důležité

Každý prostředek Web PubSub musí mít jedinečný název. V následujících příkladech nahraďte <your-unique-resource-name> názvem svého Web PubSub.

az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1

Výstup tohoto příkazu zobrazuje vlastnosti nově vytvořeného prostředku. Poznamenejte si hodnoty dvou vlastností uvedených níže:

  • Název prostředku: Název, který jste zadali do výše uvedeného parametru --name.
  • hostName: V příkladu je <your-unique-resource-name>.webpubsub.azure.com/název hostitele .

V tuto chvíli je váš účet Azure jediným autorizovaným k provádění jakýchkoli operací s tímto novým prostředkem.

Získejte ConnectionString pro pozdější použití

Připojovací řetězce v původní podobě se v tomto článku uvádějí pouze pro demonstrační účely. V produkčních prostředích vždy chraňte přístupové klíče. Pomocí služby Azure Key Vault můžete bezpečně spravovat a obměňovat klíče a zabezpečit připojení WebPubSubServiceClient.

Pomocí příkazu Azure CLI az webpubsub key získejte ConnectionString služby. <your-unique-resource-name> Zástupný symbol nahraďte názvem vaší instance Azure Web PubSub.

az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv

Zkopírujte připojovací řetězec pro pozdější použití.

Zkopírujte načtený ConnectionString a použijte později v tomto kurzu jako hodnotu <connection_string>.

Nastavení projektu

Požadavky

Použití podprotokolu

Klient může navázat připojení protokolu WebSocket pomocí konkrétního subprotokolu. Služba Azure Web PubSub podporuje podprotokol s názvem json.webpubsub.azure.v1, který klientům umožňuje publikovat a odebírat zprávy přímo prostřednictvím služby Web PubSub místo komunikace tam a zpět s nadřazeným serverem. Podrobnosti o subprotokolu najdete v článku Podporovaný subprotokol JSON WebSocket ve službě Azure Web PubSub.

Pokud používáte jiné názvy protokolů, služba je bude ignorovat a předá je serveru v obsluze události connect, takže si můžete vytvořit vlastní protokoly.

Teď vytvoříme webovou aplikaci pomocí subprotocolu json.webpubsub.azure.v1 .

  1. Nainstalujte závislosti

    mkdir logstream
    cd logstream
    dotnet new web
    dotnet add package Microsoft.Extensions.Azure
    dotnet add package Azure.Messaging.WebPubSub
    
  2. Vytvořte serverovou stranu pro hostování /negotiate rozhraní API a webové stránky.

    Aktualizujte Program.cs níže uvedeným kódem.

    • Použijte AddAzureClients k přidání klienta služby a načtení připojovacího řetězce z konfigurace.
    • Přidejte app.UseStaticFiles(); před app.Run(); podporu statických souborů.
    • Aktualizujte app.MapGet a vygenerujte přístupový token klienta pomocí požadavků /negotiate.
    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. Vytvoření webové stránky

    Vytvořte stránku HTML s následujícím obsahem a uložte ji jako 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>                                                                
    

    Výše uvedený kód se připojí ke službě a vytiskne všechny přijaté zprávy na stránku. Hlavní změnou je, že při vytváření připojení WebSocket určíme subprotocol.

  4. Spuštění serveru

    K nastavení připojovacího řetězce používáme nástroj Secret Manager pro .NET Core. Spusťte následující příkaz, nahraďte <connection_string> hodnotou získanou v předchozím kroku a otevřete http://localhost:5000/index.html v prohlížeči:

    dotnet user-secrets init
    dotnet user-secrets set Azure:WebPubSub:ConnectionString "<connection-string>"
    dotnet run
    

    Pokud používáte Chrome, můžete stisknout klávesu F12 nebo kliknout pravým tlačítkem na ->Prozkoumat ->Nástroje pro vývojáře a vybrat kartu Síť. Načtěte webovou stránku a uvidíte, že připojení WebSocket bylo navázáno. Vyberte možnost zkontrolovat připojení WebSocket; níže vidíte, že klient obdržel následující connected zprávu události. Je vidět, že pro tohoto klienta lze vygenerovat connectionId.

    {"type":"system","event":"connected","userId":null,"connectionId":"<the_connection_id>"}
    

Je vidět, že pomocí subprotokolu můžete získat některá metadata o připojení, když je připojení connected.

Klient teď místo prostého textu obdrží zprávu JSON. Zpráva JSON obsahuje další informace, jako je typ a zdroj zprávy. Tyto informace tedy můžete použít k dalšímu zpracování zprávy (například zobrazení zprávy v jiném stylu, pokud pochází z jiného zdroje), které najdete v dalších částech.

Publikování zpráv z klienta

V kurzu Vytvoření chatovací aplikace, když klient odešle zprávu prostřednictvím připojení WebSocket do služby Web PubSub, služba na straně vašeho serveru aktivuje uživatelskou událost. V případě subprotocolu má klient více funkcí odesláním zprávy JSON. Můžete například publikovat zprávy přímo z klienta prostřednictvím služby Web PubSub jiným klientům.

To je užitečné, pokud chcete streamovat velké množství dat jiným klientům v reálném čase. Pomocí této funkce vytvoříme aplikaci streamování protokolů, která může streamovat protokoly konzoly do prohlížeče v reálném čase.

  1. Vytvoření streamovacího programu

    Vytvořte program stream:

    mkdir stream
    cd stream
    dotnet new console
    

    Aktualizujte Program.cs následujícím obsahem:

    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; }
            }
        }
    }
    
    

    Vidíte, že je zde nový koncept „group“. Skupina je logickým konceptem v rámci hubu, kde můžete odeslat zprávu skupině připojení. V centru můžete mít více skupin a jeden klient se může přihlásit k odběru více skupin současně. Při použití subprotocolu můžete publikovat pouze do skupiny místo vysílání do celého centra. Podrobnosti o termínech najdete v základních konceptech.

  2. Protože zde používáme skupinu, musíme také aktualizovat webovou stránku index.html, aby se připojila ke skupině po navázání připojení WebSocket v callbacku ws.onopen.

    let ackId = 0;
    ws.onopen = () => {
      console.log('connected');
      ws.send(JSON.stringify({
        type: 'joinGroup',
        group: 'stream',
        ackId: ++ackId
      }));
    };
    

    Klient se ke skupině připojí tak, že odešle zprávu typu joinGroup .

  3. Také mírně upravte logiku ws.onmessage callbacku tak, aby parsovala odpověď ve formátu JSON a vypisovala pouze zprávy ze skupiny stream, takže bude fungovat jako výpis živého streamu.

    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. Z bezpečnostních důvodů se klient ve výchozím nastavení nemůže sám přihlásit ke skupině ani do ní publikovat. Všimli jste si tedy, že jsme při generování tokenu nastavili pro klienta roles:

    Nastavte roles, když je GenerateClientAccessUri v Startup.cs, jak je uvedeno níže:

    service.GenerateClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" })
    
  5. Nakonec také použijte pro index.html nějaký styl, aby se zobrazoval hezky.

    <html>
    
      <head>
        <style>
          #output {
            white-space: pre;
            font-family: monospace;
          }
        </style>
      </head>
    

Teď spusťte následující kód a zadejte libovolný text a zobrazí se v prohlížeči v reálném čase:

ls -R | dotnet run

# Or call `dir /s /b | dotnet run` when you are using CMD under Windows

Nebo to zvolníte, abyste viděli, že se data streamují do prohlížeče v reálném čase:

for i in $(ls -R); do echo $i; sleep 0.1; done | dotnet run

Kompletní vzorový kód tohoto kurzu najdete tady.

Další kroky

V tomto kurzu najdete základní představu o tom, jak se připojit ke službě Web PubSub a jak publikovat zprávy do připojených klientů pomocí subprotocolu.

Projděte si další kurzy, ve které se dozvíte, jak službu používat.