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 ještě nemáte předplatné Azure, vytvořte si bezplatný účet Azure 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.

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 eastus umístění.

az group create --name myResourceGroup --location EastUS

Vytvoření instance Web PubSub

Spuštěním příkazu az extension add nainstalujte nebo upgradujte rozšíření webpubsub na aktuální verzi.

az extension add --upgrade --name webpubsub

Pomocí příkazu az webpubsub az webpubsub vytvořte web pubSub ve skupině prostředků, kterou jste vytvořili. 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 <název_prostředku-unique-resource názvem> podsítě 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 výše uvedenému 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ískání Připojení ionString pro budoucí použití

Důležité

Připojovací řetězec obsahuje informace o autorizaci vyžadované pro vaši aplikaci pro přístup ke službě Azure Web PubSub. Přístupový klíč uvnitř připojovací řetězec je podobný kořenovému heslu pro vaši službu. Vprodukčních Pomocí služby Azure Key Vault můžete klíče bezpečně spravovat a otáčet. 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.

Pomocí příkazu azure CLI az webpubsub key získejte Připojení ionString 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čtenou Připojení ionString a použijte později v tomto kurzu jako hodnotu <connection_string>.

Nastavení projektu

Požadavky

Použití dílčího souhrnu

Klient může spustit připojení WebSocket pomocí konkrétního dílčího protokolu. Služba Azure Web PubSub podporuje podprotokol, json.webpubsub.azure.v1 která umožňuje klientům provádět publikování a odběr přímo prostřednictvím služby Web PubSub místo doby odezvy na nadřazený server. Podrobnosti o subprotocolu pro podsoučet websocketu ve službě Azure Web PubSub podporuje JSON WebSocket.

Pokud používáte jiné názvy protokolů, služba je bude ignorovat a předat server v obslužné rutině události connect, takže můžete vytvořit vlastní protokoly.

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

  1. Instalace závislostí

    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 ho následujícím kódem.

    • Slouží AddAzureClients k přidání klienta služby a čtení připojovací řetězec z konfigurace.
    • Přidejte app.UseStaticFiles(); před app.Run(); podporu statických souborů.
    • Aktualizujte a vygenerujte app.MapGet přístupový token klienta s /negotiate požadavky.
    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í řetězec používáme nástroj Secret Manager pro .NET Core. Spusťte následující příkaz, nahraďte <connection_string> ho načítaným v předchozím kroku a otevřete http://localhost:5000/index.html ho 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 -Inspect ->>Developer Tools a vybrat kartu Síť. Načtěte webovou stránku a uvidíte, že je navázáno připojení WebSocket. Vyberte, pokud chcete zkontrolovat připojení WebSocket, v klientovi se zobrazí následující connected zpráva události. Vidíte, že pro tohoto klienta můžete získat vygenerované connectionId .

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

Můžete vidět, že pomocí subprotocol, můžete získat metadata připojení, když je connectedpřipojení .

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

Když klient odešle zprávu prostřednictvím připojení WebSocket ke službě Web PubSub, spustí v kurzu k vytvoření chatovací aplikace událost uživatele na straně serveru. 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ření stream programu:

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

    Tady vidíte nový koncept "group". Skupina je logický koncept v centru, kde můžete publikovat zprávu do skupiny 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. Vzhledem k tomu, že zde používáme skupinu, musíme také aktualizovat webovou stránku index.html , aby se připojila ke skupině při navázání připojení WebSocket uvnitř ws.onopen zpětného volání.

    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é aktualizujte logiku zpětného ws.onmessage volání mírně tak, aby parsuje odpověď JSON a vytiskla zprávy pouze ze stream skupiny tak, aby funguje jako tiskárna živého datového proudu.

    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 hlediska zabezpečení nemůže klient ve výchozím nastavení publikovat nebo přihlásit k odběru skupiny sám sebe. Všimli jste si tedy, že jsme při generování tokenu nastavili roles klienta:

    Nastavte následující rolesGenerateClientAccessUriStartup.cs :

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

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