Aracılığıyla paylaş


Öğretici: Azure Web PubSub hizmetiyle sohbet uygulaması oluşturma

İleti yayımlama ve abone olma öğreticisinde, Azure Web PubSub ile iletileri yayımlama ve abone olma ile ilgili temel bilgileri öğrenirsiniz. Bu öğreticide Azure Web PubSub'un olay sistemini öğrenecek ve gerçek zamanlı iletişim işlevselliğine sahip eksiksiz bir web uygulaması oluşturmak için kullanacaksınız.

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

  • Web PubSub hizmet örneği oluşturma
  • Azure Web PubSub için olay işleyici ayarlarını yapılandırma
  • Uygulama sunucusunda Hanlde olayları ve gerçek zamanlı sohbet uygulaması oluşturma

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'i kopyalayın ve daha sonra öğreticinin okuduğu ortam değişkenine WebPubSubConnectionStringayarlayın. Aşağıdaki değerini, getirdiğiniz Bağlan ionString ile değiştirin<connection-string>.

export WebPubSubConnectionString="<connection-string>"
SET WebPubSubConnectionString=<connection-string>

Projeyi ayarlama

Önkoşullar

Uygulamayı oluşturma

Azure Web PubSub'da sunucu ve istemci olarak iki rol vardır. Bu kavram, bir web uygulamasındaki sunucu ve istemci rollerine benzer. Sunucu, istemcileri yönetmek, dinlemek ve istemci iletilerini yanıtlamakla sorumludur. İstemci, kullanıcının iletilerini sunucudan gönderip almaktan ve son kullanıcı için görselleştirmekten sorumludur.

Bu öğreticide, gerçek zamanlı bir sohbet web uygulaması oluşturacağız. Gerçek bir web uygulamasında, sunucunun sorumluluğu istemcilerin kimliğini doğrulamayı ve uygulama kullanıcı arabirimi için statik web sayfaları sunmayı da içerir.

Web sayfalarını barındırmak ve gelen istekleri işlemek için ASP.NET Core 8 kullanıyoruz.

İlk olarak bir klasörde ASP.NET Core web uygulaması chatapp oluşturalım.

  1. Yeni bir web uygulaması oluşturun.

    mkdir chatapp
    cd chatapp
    dotnet new web
    
  2. Statik web sayfalarını barındırmayı desteklemek için Program.cs ekleyin app.UseStaticFiles() .

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.UseStaticFiles();
    
    app.Run();
    
  3. Bir HTML dosyası oluşturun ve olarak wwwroot/index.htmlkaydedin. Bunu daha sonra sohbet uygulamasının kullanıcı arabirimi için kullanacağız.

    <html>
      <body>
        <h1>Azure Web PubSub Chat</h1>
      </body>
    </html>
    

Tarayıcıda çalıştırarak dotnet run --urls http://localhost:8080 ve bu sunucuya erişerek http://localhost:8080/index.html sunucuyu test edebilirsiniz.

Anlaşma uç noktası ekleme

Yayımlama ve abone olma iletisi öğreticisinde, abone bağlantı dizesi doğrudan tüketir. Bağlantı dizesi hizmete herhangi bir işlem yapmak için yüksek ayrıcalığı olduğundan, gerçek bir dünya uygulamasında bağlantı dizesi herhangi bir istemciyle paylaşmak güvenli değildir. Şimdi sunucunuzun bağlantı dizesi kullanmasını ve istemcinin erişim belirteci ile tam URL'yi alması için bir negotiate uç noktayı kullanıma sunun. Bu şekilde, sunucu yetkisiz erişimi önlemek için uç noktanın negotiate önüne kimlik doğrulama ara yazılımı ekleyebilir.

İlk olarak bağımlılıkları yükleyin.

dotnet add package Microsoft.Azure.WebPubSub.AspNetCore

Şimdi belirteci oluşturmak üzere istemcisinin çağıracağı bir /negotiate uç nokta ekleyelim.

using Azure.Core;
using Microsoft.Azure.WebPubSub.AspNetCore;
using Microsoft.Azure.WebPubSub.Common;
using Microsoft.Extensions.Primitives;

// Read connection string from environment
var connectionString = Environment.GetEnvironmentVariable("WebPubSubConnectionString");
if (connectionString == null)
{
    throw new ArgumentNullException(nameof(connectionString));
}

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddWebPubSub(o => o.ServiceEndpoint = new WebPubSubServiceEndpoint(connectionString))
    .AddWebPubSubServiceClient<Sample_ChatApp>();
var app = builder.Build();

app.UseStaticFiles();

// return the Client Access URL with negotiate endpoint
app.MapGet("/negotiate", (WebPubSubServiceClient<Sample_ChatApp> service, HttpContext context) =>
{
    var id = context.Request.Query["id"];
    if (StringValues.IsNullOrEmpty(id))
    {
        context.Response.StatusCode = 400;
        return null;
    }
    return new
    {
        url = service.GetClientAccessUri(userId: id).AbsoluteUri
    };
});
app.Run();

sealed class Sample_ChatApp : WebPubSubHub
{
}

AddWebPubSubServiceClient<THub>() , istemci bağlantı belirteci oluşturmak için anlaşma adımında ve hub olayları tetiklendiğinde hizmet REST API'lerini çağırmak için hub yöntemlerinde kullanabileceğimiz hizmet istemcisini WebPubSubServiceClient<THub>eklemek için kullanılır. Bu belirteç oluşturma kodu, yayımlama ve abone olma iletisi öğreticisinde kullandığımız koda benzer, ancak belirteci oluştururken bir bağımsız değişken daha (userId) geçiririz. kullanıcı kimliği istemci kimliğini tanımlamak için kullanılabilir, böylece bir ileti aldığınızda iletinin nereden geldiğini bilirsiniz.

Kod, önceki adımda ayarladığımız ortam değişkenindeki WebPubSubConnectionString bağlantı dizesi okur.

kullanarak dotnet run --urls http://localhost:8080sunucuyu yeniden çalıştırın.

Bu API'ye erişerek http://localhost:8080/negotiate?id=user1 test edebilirsiniz ve size erişim belirteci ile Azure Web PubSub'un tam URL'sini verir.

Olayları işleme

Azure Web PubSub'da, istemci tarafında belirli etkinlikler gerçekleştiğinde (örneğin bir istemci bağlanıyor, bağlı, bağlantısı kesiliyor veya bir istemci ileti gönderiyorsa), hizmet bu olaylara tepki verebilmesi için sunucuya bildirimler gönderir.

Olaylar web kancası biçiminde sunucuya teslim edilir. Web kancası uygulama sunucusu tarafından sunulur ve kullanıma sunulur ve Azure Web PubSub hizmeti tarafında kaydedilir. Bir olay gerçekleştiğinde hizmet web kancalarını çağırır.

Azure Web PubSub, olay verilerini açıklamak için CloudEvents'i izler.

Aşağıda, bir istemci bağlandığında sistem olaylarını ve bir istemci sohbet uygulamasını derlemek için ileti gönderirken kullanıcı olaylarını ele message alıyoruzconnected.

Önceki adımda yüklediğimiz AspNetCore Microsoft.Azure.WebPubSub.AspNetCore için Web PubSub SDK'sı, CloudEvents isteklerini ayrıştırma ve işlemeye de yardımcı olabilir.

İlk olarak, önüne app.Run()olay işleyicileri ekleyin. Olaylar için uç nokta yolunu (diyelim ki /eventhandler) belirtin.

app.MapWebPubSubHub<Sample_ChatApp>("/eventhandler/{*path}");
app.Run();

Şimdi, önceki adımda oluşturduğumuz sınıfın Sample_ChatApp içinde, Web PubSub hizmetini çağırmak için kullandığımız bir WebPubSubServiceClient<Sample_ChatApp> oluşturucu ekleyin. Ve OnConnectedAsync() olay tetiklendiğinde connected yanıt vermek, OnMessageReceivedAsync() istemciden gelen iletileri işlemek için.

sealed class Sample_ChatApp : WebPubSubHub
{
    private readonly WebPubSubServiceClient<Sample_ChatApp> _serviceClient;

    public Sample_ChatApp(WebPubSubServiceClient<Sample_ChatApp> serviceClient)
    {
        _serviceClient = serviceClient;
    }

    public override async Task OnConnectedAsync(ConnectedEventRequest request)
    {
        Console.WriteLine($"[SYSTEM] {request.ConnectionContext.UserId} joined.");
    }

    public override async ValueTask<UserEventResponse> OnMessageReceivedAsync(UserEventRequest request, CancellationToken cancellationToken)
    {
        await _serviceClient.SendToAllAsync(RequestContent.Create(
        new
        {
            from = request.ConnectionContext.UserId,
            message = request.Data.ToString()
        }),
        ContentType.ApplicationJson);

        return new UserEventResponse();
    }
}

Yukarıdaki kodda, JSON biçiminde bir bildirim iletisi yayınlamak için hizmet istemcisini kullanırız ve bu iletinin tümü ile birleştirilir SendToAllAsync.

Web sayfasını güncelleştirme

Şimdi bağlanacak, ileti gönderecek ve alınan iletileri sayfada görüntüleyecek mantığı ekleyecek şekilde güncelleştirelim index.html .

<html>
  <body>
    <h1>Azure Web PubSub Chat</h1>
    <input id="message" placeholder="Type to chat...">
    <div id="messages"></div>
    <script>
      (async function () {
        let id = prompt('Please input your user name');
        let res = await fetch(`/negotiate?id=${id}`);
        let data = await res.json();
        let ws = new WebSocket(data.url);
        ws.onopen = () => console.log('connected');

        let messages = document.querySelector('#messages');
        
        ws.onmessage = event => {
          let m = document.createElement('p');
          let data = JSON.parse(event.data);
          m.innerText = `[${data.type || ''}${data.from || ''}] ${data.message}`;
          messages.appendChild(m);
        };

        let message = document.querySelector('#message');
        message.addEventListener('keypress', e => {
          if (e.charCode !== 13) return;
          ws.send(message.value);
          message.value = '';
        });
      })();
    </script>
  </body>

</html>

Yukarıdaki kodda bağlandığımız kodun tarayıcıda yerel WebSocket API'sini, ileti göndermek ve WebSocket.onmessage alınan iletileri dinlemek için kullandığını WebSocket.send() görebilirsiniz.

Ayrıca hizmete bağlanmak için İstemci SDK'larını da kullanabilirsiniz. Bu da sizi otomatik yeniden bağlama, hata işleme ve daha fazlası ile güçlendirebilir.

Artık sohbetin çalışması için bir adım kaldı. Hangi olayları önemsediğimizi ve Web PubSub hizmetinde olayları nereye gönderebileceğimizi yapılandıralım.

Olay işleyicisini ayarlama

Web PubSub hizmetinde olay işleyicisini, hizmete olayların nereye gönderileceğine söyleyecek şekilde ayarladık.

Web sunucusu yerel olarak çalıştırıldığında, web PubSub hizmeti internetten erişilebilen uç noktası yoksa localhost'ı nasıl çağırır? Genellikle iki yol vardır. Bunlardan biri, bir genel tünel aracı kullanarak localhost'un genel kullanıma sunma, diğeri ise web PubSub hizmetinden gelen trafiği yerel sunucunuza tünel oluşturmak için awps-tunnel kullanmaktır.

Bu bölümde, olay işleyicilerini ayarlamak için Azure CLI'yi ve trafiği localhost'a yönlendirmek için awps-tunnel kullanacağız.

Hub ayarlarını yapılandırma

Web PubSub'un iletileri 'nin tünel bağlantısı üzerinden awps-tunnelyönlendirmesi için URL şablonunu düzen kullanacak tunnel şekilde ayarladık. Olay işleyicileri, bu makalede açıklandığı gibi portaldan veya CLI'dan ayarlanabilir. Burada CLI aracılığıyla ayarlayacağız. Önceki adım ayarlandığı gibi yoldaki /eventhandler olayları dinlediğimiz için URL şablonunu olarak tunnel:///eventhandlerayarlarız.

Hub için olay işleyici ayarlarını oluşturmak için Sample_ChatApp Azure CLI az webpubsub hub create komutunu kullanın.

Önemli

benzersiz-kaynak-adınızı> önceki adımlardan oluşturulan Web PubSub kaynağınızın adıyla değiştirin<.

az webpubsub hub create -n "<your-unique-resource-name>" -g "myResourceGroup" --hub-name "Sample_ChatApp" --event-handler url-template="tunnel:///eventhandler" user-event-pattern="*" system-event="connected"

awps-tunnel'ı yerel olarak çalıştırma

awps-tunnel indirme ve yükleme

Araç, Node.js sürüm 16 veya üzeri üzerinde çalışır.

npm install -g @azure/web-pubsub-tunnel-tool

Hizmet bağlantı dizesi kullanma ve çalıştırma

export WebPubSubConnectionString="<your connection string>"
awps-tunnel run --hub Sample_ChatApp --upstream http://localhost:8080

Web sunucusunu çalıştırma

Artık her şey ayarlandı. Şimdi web sunucusunu çalıştıralım ve sohbet uygulamasını çalışır durumda oynatalım.

Şimdi kullanarak sunucuyu dotnet run --urls http://localhost:8080çalıştırın.

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

http://localhost:8080/index.html'ı açın. Kullanıcı adınızı girip sohbet etmeye başlayabilirsiniz.

Olay işleyicisi ile Gecikmeli connect Kimlik Doğrulaması

Önceki bölümlerde, istemcilerin Web PubSub hizmetine bağlanması için Web PubSub hizmet URL'sini ve JWT erişim belirtecini döndürmek için anlaşma uç noktasının nasıl kullanılacağını gösteriyoruz. Bazı durumlarda, örneğin, kaynakları sınırlı olan uç cihazlar, istemciler Web PubSub kaynaklarına doğrudan bağlanmayı tercih edebilir. Bu gibi durumlarda, istemcilere yavaş kimlik doğrulaması yapmak, istemcilere kullanıcı kimliği atamak, istemcilerin bağlandıktan sonra katıldığı grupları belirtmek, istemcilerin sahip olduğu izinleri ve WebSocket altprotocol'u istemciye WebSocket yanıtı olarak yapılandırmak için olay işleyicisini yapılandırabilirsinizconnect. Ayrıntılar lütfen olay işleyicisi belirtimini bağlama konusuna bakın.

Şimdi olay işleyicisini kullanarak connect anlaşma bölümünün yaptığı gibi benzer bir sonuç elde edelim.

Hub ayarlarını güncelleştirme

İlk olarak hub ayarlarını olay işleyicisini de içerecek connect şekilde güncelleştirelim. JWT erişim belirteci olmayan istemcilerin hizmete bağlanabilmesi için anonim bağlantıya da izin vermemiz gerekiyor.

Hub için olay işleyici ayarlarını oluşturmak için Sample_ChatApp Azure CLI az webpubsub hub update komutunu kullanın.

Önemli

benzersiz-kaynak-adınızı> önceki adımlardan oluşturulan Web PubSub kaynağınızın adıyla değiştirin<.

az webpubsub hub update -n "<your-unique-resource-name>" -g "myResourceGroup" --hub-name "Sample_ChatApp" --allow-anonymous true --event-handler url-template="tunnel:///eventhandler" user-event-pattern="*" system-event="connected" system-event="connect"

Bağlantı olayını işlemek için yukarı akış mantığını güncelleştirme

Şimdi bağlantı olayını işlemek için yukarı akış mantığını güncelleştirelim. Şimdi anlaşma uç noktasını da kaldırabiliriz.

Tanıtım amaçlı olarak anlaşma uç noktasında yaptıklarımıza benzer şekilde sorgu parametrelerinden kimlik de okuruz. Connect olayında, özgün istemci sorgusu bağlanma olayı requet gövdesinde korunur.

sınıfının Sample_ChatAppiçinde, olayı işlemek connect için öğesini geçersiz kılınOnConnectAsync():

sealed class Sample_ChatApp : WebPubSubHub
{
    private readonly WebPubSubServiceClient<Sample_ChatApp> _serviceClient;

    public Sample_ChatApp(WebPubSubServiceClient<Sample_ChatApp> serviceClient)
    {
        _serviceClient = serviceClient;
    }

    public override ValueTask<ConnectEventResponse> OnConnectAsync(ConnectEventRequest request, CancellationToken cancellationToken)
    {
        if (request.Query.TryGetValue("id", out var id))
        {
            return new ValueTask<ConnectEventResponse>(request.CreateResponse(userId: id.FirstOrDefault(), null, null, null));
        }

        // The SDK catches this exception and returns 401 to the caller
        throw new UnauthorizedAccessException("Request missing id");
    }

    public override async Task OnConnectedAsync(ConnectedEventRequest request)
    {
        Console.WriteLine($"[SYSTEM] {request.ConnectionContext.UserId} joined.");
    }

    public override async ValueTask<UserEventResponse> OnMessageReceivedAsync(UserEventRequest request, CancellationToken cancellationToken)
    {
        await _serviceClient.SendToAllAsync(RequestContent.Create(
        new
        {
            from = request.ConnectionContext.UserId,
            message = request.Data.ToString()
        }),
        ContentType.ApplicationJson);

        return new UserEventResponse();
    }
}

Index.html doğrudan bağlanacak şekilde güncelleştirme

Şimdi Web PubSub hizmetine doğrudan bağlanmak için web sayfasını güncelleştirelim. Bahsetmeniz gereken bir nokta, tanıtım amacıyla Web PubSub hizmet uç noktasının istemci koduna sabit kodlanmış olmasıdır. Lütfen aşağıdaki html'deki hizmet ana bilgisayar adını <the host name of your service> kendi hizmetinizdeki değerle güncelleştirin. Web PubSub hizmet uç noktası değerini sunucunuzdan getirmek hala yararlı olabilir; istemcinin bağlandığı yere daha fazla esneklik ve denetlenebilirlik sağlar.

<html>
  <body>
    <h1>Azure Web PubSub Chat</h1>
    <input id="message" placeholder="Type to chat...">
    <div id="messages"></div>
    <script>
      (async function () {
        // sample host: mock.webpubsub.azure.com
        let hostname = "<the host name of your service>";
        let id = prompt('Please input your user name');
        let ws = new WebSocket(`wss://${hostname}/client/hubs/Sample_ChatApp?id=${id}`);
        ws.onopen = () => console.log('connected');

        let messages = document.querySelector('#messages');
        
        ws.onmessage = event => {
          let m = document.createElement('p');
          let data = JSON.parse(event.data);
          m.innerText = `[${data.type || ''}${data.from || ''}] ${data.message}`;
          messages.appendChild(m);
        };

        let message = document.querySelector('#message');
        message.addEventListener('keypress', e => {
          if (e.charCode !== 13) return;
          ws.send(message.value);
          message.value = '';
        });
      })();
    </script>
  </body>

</html>

Sunucuyu yeniden çalıştırma

Şimdi sunucuyu yeniden çalıştırın ve önceki yönergeleri izleyerek web sayfasını ziyaret edin. 'yi durdurduysanız awps-tunnellütfen tünel aracını da yeniden çalıştırın.

Sonraki adımlar

Bu öğretici, Azure Web PubSub hizmetinde olay sisteminin nasıl çalıştığı 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.