Öğretici: Altprotocol kullanarak WebSocket istemcileri arasında ileti yayımlama ve abone olma

Sohbet uygulaması oluşturma öğreticisinde, Azure Web PubSub ile veri göndermek ve almak için WebSocket API'lerini kullanmayı öğrendiniz. İstemci hizmetle iletişim kurarken gerekli bir protokol olmadığını görebilirsiniz. Örneğin, kullanarak WebSocket.send()herhangi bir veri türünü gönderebilirsiniz ve sunucu bu verileri olduğu gibi alır. WebSocket API'leri işleminin kullanımı kolaydır, ancak işlevsellik sınırlıdır. Örneğin, olayı sunucunuza gönderirken olay adını belirtemez veya iletiyi sunucunuza göndermek yerine diğer istemcilere yayımlayamazsınız. Bu öğreticide, istemcinin işlevselliğini genişletmek için alt protokol kullanmayı öğreneceksiniz.

Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:

  • Web PubSub hizmet örneği oluşturma
  • WebSocket bağlantısını kurmak için tam URL'yi oluşturma
  • Altprotocol kullanarak WebSocket istemcileri arasında ileti yayımlama

Azure aboneliğiniz yoksa başlamadan önce birücretsiz Azure hesabı oluşturun.

Önkoşullar

  • Azure Cloud Shell'de Bash ortamını kullanın. Daha fazla bilgi için bkz . Azure Cloud Shell'de Bash için hızlı başlangıç.

  • CLI başvuru komutlarını yerel olarak çalıştırmayı tercih ediyorsanız Azure CLI'yı yükleyin . Windows veya macOS üzerinde çalışıyorsanız Azure CLI’yi bir Docker kapsayıcısında çalıştırmayı değerlendirin. Daha fazla bilgi için bkz . Docker kapsayıcısında Azure CLI'yi çalıştırma.

    • Yerel yükleme kullanıyorsanız az login komutunu kullanarak Azure CLI ile oturum açın. Kimlik doğrulama işlemini tamamlamak için terminalinizde görüntülenen adımları izleyin. Diğer oturum açma seçenekleri için bkz . Azure CLI ile oturum açma.

    • İstendiğinde, ilk kullanımda Azure CLI uzantısını yükleyin. Uzantılar hakkında daha fazla bilgi için bkz. Azure CLI ile uzantıları kullanma.

    • Yüklü sürümü ve bağımlı kitaplıkları bulmak için az version komutunu çalıştırın. En son sürüme yükseltmek için az upgrade komutunu çalıştırın.

  • Bu kurulum, Azure CLI'nın 2.22.0 veya üzeri bir sürümünü gerektirir. Azure Cloud Shell kullanılıyorsa en son sürüm zaten yüklüdür.

Azure Web PubSub örneği oluşturma

Kaynak grubu oluşturma

Kaynak grubu, Azure kaynaklarının dağıtıldığı ve yönetildiği bir mantıksal kapsayıcıdır. konumunda adlı myResourceGroup eastus bir kaynak grubu oluşturmak için az group create komutunu kullanın.

az group create --name myResourceGroup --location EastUS

Web PubSub örneği oluşturma

Webpubsub uzantısını yüklemek veya geçerli sürüme yükseltmek için az extension add komutunu çalıştırın.

az extension add --upgrade --name webpubsub

Oluşturduğunuz kaynak grubunda bir Web PubSub oluşturmak için Azure CLI az webpubsub create komutunu kullanın. Aşağıdaki komut, EastUS'ta myResourceGroup kaynak grubu altında bir Ücretsiz Web PubSub kaynağı oluşturur:

Önemli

Her Web PubSub kaynağının benzersiz bir adı olmalıdır. Aşağıdaki örneklerde unique-resource-name> değerini Web PubSub'ınızın adıyla değiştirin<.

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

Bu komutun çıktısı yeni oluşturulan kaynağın özelliklerini gösterir. Aşağıda listelenen iki özelliği not edin:

  • Kaynak Adı: Yukarıdaki parametreye --name sağladığınız ad.
  • hostName: Örnekte ana bilgisayar adı şeklindedir <your-unique-resource-name>.webpubsub.azure.com/.

Bu noktada, azure hesabınız bu yeni kaynak üzerinde herhangi bir işlem gerçekleştirme yetkisi olan tek hesaptır.

Gelecekte kullanmak üzere Bağlan ionString'i edinin

Önemli

bağlantı dizesi, uygulamanızın Azure Web PubSub hizmetine erişmesi için gereken yetkilendirme bilgilerini içerir. bağlantı dizesi içindeki erişim anahtarı, hizmetinizin kök parolasına benzer. Üretim ortamlarında erişim anahtarlarınızı korumak için her zaman dikkatli olun. Anahtarlarınızı güvenli bir şekilde yönetmek ve döndürmek için Azure Key Vault'ı kullanın. Erişim anahtarlarını diğer kullanıcılara dağıtmaktan, sabit kodlamaktan veya başkalarının erişebileceği herhangi bir yerde düz metin olarak kaydetmekten kaçının. Ele geçirilmiş olabileceklerini düşünüyorsanız anahtarlarınızı döndürün.

Hizmetin Bağlan ionString'ini almak için Azure CLI az webpubsub key komutunu kullanın. Yer tutucuyu <your-unique-resource-name> Azure Web PubSub örneğinizin adıyla değiştirin.

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

Daha sonra kullanmak üzere bağlantı dizesi kopyalayın.

Getirilen Bağlan ionString değerini kopyalayın ve bu öğreticinin devamında değerini <connection_string>kullanın.

Projeyi ayarlama

Önkoşullar

Altprotocol kullanma

İstemci, belirli bir altprotocol kullanarak bir WebSocket bağlantısı başlatabilir. Azure Web PubSub hizmeti, istemcilerin yukarı akış sunucusuna gidiş dönüş yerine doğrudan Web PubSub hizmeti aracılığıyla yayımlama/abone olma yetkisi vermek için adlı json.webpubsub.azure.v1 bir alt projeyi destekler. Altprotocol hakkında ayrıntılı bilgi için Azure Web PubSub tarafından desteklenen JSON WebSocket altprotocol bölümüne bakın.

Başka protokol adları kullanırsanız, bunlar hizmet tarafından yoksayılır ve bağlantı olay işleyicisindeki sunucuya geçirilerek kendi protokollerinizi oluşturabilirsiniz.

Şimdi altprotokolü kullanarak json.webpubsub.azure.v1 bir web uygulaması oluşturalım.

  1. Bağımlılıkları yükleme

    mkdir logstream
    cd logstream
    dotnet new web
    dotnet add package Microsoft.Extensions.Azure
    dotnet add package Azure.Messaging.WebPubSub
    
  2. API'yi ve web sayfasını barındırmak /negotiate için sunucu tarafı oluşturun.

    Aşağıdaki kodla güncelleştirin Program.cs .

    • Hizmet istemcisini eklemek ve yapılandırmadan bağlantı dizesi okumak için kullanınAddAzureClients.
    • Statik dosyaları desteklemek için daha önce app.Run(); ekleyinapp.UseStaticFiles();.
    • ve isteklerle /negotiate istemci erişim belirtecini oluşturacak şekilde güncelleştirinapp.MapGet.
    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. Web sayfasını oluşturma

    Aşağıdaki içeriğe sahip bir HTML sayfası oluşturun ve olarak wwwroot/index.htmlkaydedin:

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

    Yukarıdaki kod hizmete bağlanır ve sayfaya alınan tüm iletileri yazdırır. Ana değişiklik, WebSocket bağlantısını oluştururken altprotokolü belirtmemizdir.

  4. Sunucuyu çalıştırma

    bağlantı dizesi ayarlamak için .NET Core için Gizli Dizi Yöneticisi aracını kullanırız. Öğesini önceki adımda getirilen komutla değiştirerek <connection_string> aşağıdaki komutu çalıştırın ve tarayıcıda açınhttp://localhost:5000/index.html:

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

    Chrome kullanıyorsanız F12 tuşuna basabilir veya -Inspect ->>Developer Tools'a sağ tıklayıp Ağ sekmesini seçebilirsiniz. Web sayfasını yüklediğinizde WebSocket bağlantısının kurulduğunu görebilirsiniz. WebSocket bağlantısını incelemek için seçin, istemcide aşağıdaki connected olay iletisinin alındiğini görebilirsiniz. Bu istemci için oluşturulanı alabileceğinizi connectionId görebilirsiniz.

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

Altprotocol yardımıyla bağlantı olduğunda bağlantının bazı meta verilerini alabileceğinizi connectedgörebilirsiniz.

İstemci artık düz metin yerine bir JSON iletisi alır. JSON iletisi, iletinin türü ve kaynağı gibi daha fazla bilgi içerir. Bu nedenle, iletide daha fazla işlem yapmak için bu bilgileri kullanabilirsiniz (örneğin, ileti farklı bir kaynaktan geliyorsa farklı bir stilde görüntülenir), sonraki bölümlerde bulabilirsiniz.

İstemciden ileti yayımlama

Sohbet uygulaması oluşturma öğreticisinde, istemci Web PubSub hizmetine WebSocket bağlantısı üzerinden bir ileti gönderdiğinde, hizmet sunucu tarafınızda bir kullanıcı olayını tetikler. Altprotocol ile istemci, JSON iletisi göndererek daha fazla işleve sahiptir. Örneğin, iletileri doğrudan Web PubSub hizmeti aracılığıyla istemciden diğer istemcilere yayımlayabilirsiniz.

Bu, büyük miktarda veriyi diğer istemcilere gerçek zamanlı olarak akışla göndermek istiyorsanız kullanışlıdır. Şimdi bu özelliği kullanarak konsol günlüklerini gerçek zamanlı olarak tarayıcıya aktarabilen bir günlük akışı uygulaması oluşturalım.

  1. Akış programı oluşturma

    stream Program oluşturma:

    mkdir stream
    cd stream
    dotnet new console
    

    Aşağıdaki içerikle güncelleştirin Program.cs :

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

    Burada yeni bir "grup" kavramı olduğunu görebilirsiniz. Grup, bir bağlantı grubuna ileti yayımlayabileceğiniz bir hub'daki mantıksal kavramdır. Bir hub'da birden çok gruba sahip olabilirsiniz ve bir istemci aynı anda birden çok gruba abone olabilir. Altprotocol kullanırken, hub'ın tamamına yayınlamak yerine yalnızca bir gruba yayımlayabilirsiniz. Terimler hakkında ayrıntılı bilgi için temel kavramları gözden geçirin.

  2. Burada grubu kullandığımızdan, WebSocket bağlantısı geri çağırma içinde ws.onopen kurulduğunda gruba katılmak için web sayfasını index.html da güncelleştirmemiz gerekir.

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

    türünde bir ileti joinGroup göndererek istemcinin gruba katıldığını görebilirsiniz.

  3. Ayrıca JSON yanıtını ws.onmessage ayrıştırmak için geri çağırma mantığını biraz güncelleştirin ve iletileri yalnızca gruptan stream yazdırarak canlı akış yazıcısı işlevi görebilmesini sağlayın.

    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. Güvenlikle ilgili dikkat edilmesi gerekenler için, istemci varsayılan olarak bir grubu tek başına yayımlayamaz veya gruba abone olamaz. Bu nedenle belirteci oluştururken istemciye ayarlandığımızı roles fark ettiniz:

    when GenerateClientAccessUri değerini roles Startup.cs aşağıdaki gibi ayarlayın:

    service.GenerateClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" })
    
  5. Son olarak, düzgün bir şekilde görüntülenebilmesi için bazı index.html stil de uygulayın.

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

Şimdi aşağıdaki kodu çalıştırın ve herhangi bir metin yazın; bunlar tarayıcıda gerçek zamanlı olarak görüntülenir:

ls -R | dotnet run

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

Alternatif olarak, verilerin gerçek zamanlı olarak tarayıcıya akışını görebilmek için verileri daha yavaş hale getirirsiniz:

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

Bu öğreticinin tam kod örneğini burada bulabilirsiniz.

Sonraki adımlar

Bu öğretici, Web PubSub hizmetine bağlanma ve altprotocol kullanarak bağlı istemcilere ileti yayımlama hakkında temel bir fikir sağlar.

Hizmetin nasıl kullanılacağı hakkında daha fazla bilgi edinmek için diğer öğreticileri gözden geçirin.