Öğretici: Azure İşlevleri ve Azure Web PubSub hizmetiyle sunucusuz gerçek zamanlı sohbet uygulaması oluşturma

Azure Web PubSub hizmeti, WebSockets ve yayımlama-abone olma desenini kullanarak gerçek zamanlı mesajlaşma web uygulamaları oluşturmanıza yardımcı olur. Azure İşlevleri, herhangi bir altyapı yönetimine gerek kalmadan kodunuzu çalıştırmanıza olanak tanıyan sunucusuz bir platformdur. Bu öğreticide Azure Web PubSub hizmetini kullanmayı ve gerçek zamanlı mesajlaşma ve yayımlama-abone olma düzeniyle sunucusuz bir uygulama oluşturmak için Azure İşlevleri öğreneceksiniz.

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

  • Sunucusuz gerçek zamanlı sohbet uygulaması oluşturma
  • Web PubSub işlevi tetikleyici bağlamaları ve çıkış bağlamalarıyla çalışma
  • İşlevi Azure İşlev Uygulamasına dağıtma
  • Azure Kimlik Doğrulamayı Yapılandırma
  • Olayları ve iletileri uygulamaya yönlendirmek için Web PubSub Olay İşleyicisi'ni yapılandırma

Önkoşullar

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

Azure'da oturum açma

Azure hesabınızla Azure portalın https://portal.azure.com/ sayfasında oturum açın.

Azure Web PubSub hizmet örneği oluşturma

Uygulamanız Azure'da bir Web PubSub hizmet örneğine bağlanır.

  1. Azure portalın sol üst köşesinde bulunan Yeni düğmesini seçin. Yeni ekranında, arama kutusuna Web PubSub yazın ve Enter tuşuna basın. (Kategoriden Azure Web PubSub'da Web da arama da edebilirsiniz.)

    Portalda Azure Web PubSub araması ekran görüntüsü.

  2. Arama sonuçlarından Web PubSub'ı ve ardından Oluştur'u seçin.

  3. Aşağıdaki ayarları girin.

    Ayar Önerilen değer Açıklama
    Kaynak adı Genel olarak benzersiz bir ad Yeni Web PubSub hizmet örneğinizi tanımlayan genel olarak benzersiz Ad. Geçerli karakterler : a-z, A-Z, 0-9ve -.
    Abonelik Aboneliğiniz Bu yeni Web PubSub hizmet örneğinin oluşturulduğu Azure aboneliği.
    Kaynak Grubu myResourceGroup Web PubSub hizmet örneğinizin oluşturulacağı yeni kaynak grubunun adı.
    Konum Batı ABD Size yakın olan bir bölgeyi seçin.
    Fiyatlandırma katmanı Ücretsiz Önce Azure Web PubSub hizmetini ücretsiz deneyebilirsiniz. Azure Web PubSub hizmeti fiyatlandırma katmanları hakkında daha fazla bilgi edinin
    Birim sayısı - Birim sayısı, Web PubSub hizmet örneğinizin kabul edebileceği bağlantı sayısını belirtir. Her birim en fazla 1.000 eşzamanlı bağlantıyı destekler. Bu yalnızca Standart katmanda yapılandırılabilir.

    Portalda Azure Web PubSub örneğini oluşturma işleminin ekran görüntüsü.

  4. Web PubSub hizmet örneğini dağıtmaya başlamak için Oluştur'u seçin.

İşlevleri oluşturma

  1. Azure İşlevleri Temel Araçları'nın yüklü olduğundan emin olun. Ardından proje için boş bir dizin oluşturun. Komutunu bu çalışma dizininin altında çalıştırın.

    func init --worker-runtime javascript --model V4
    
  2. Microsoft.Azure.WebJobs.Extensions.WebPubSub yükleyin.

    Web PubSub desteği almak için uzantısıBundle'ı sürüm 4.* veya sonraki bir sürüme onaylayın ve güncelleştirinhost.json.

    {
      "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[4.*, 5.0.0)"
      }
    }
    
  3. İstemciler için statik bir index web sayfasını okumak ve barındırmak için bir işlev oluşturun.

    func new -n index -t HttpTrigger
    
    • Aşağıdaki kodları güncelleştirin src/functions/index.js ve kopyalayın.
      const { app } = require('@azure/functions');
      const { readFile } = require('fs/promises');
      
      app.http('index', {
          methods: ['GET', 'POST'],
          authLevel: 'anonymous',
          handler: async (context) => {
              const content = await readFile('index.html', 'utf8', (err, data) => {
                  if (err) {
                      context.err(err)
                      return
                  }
              });
      
              return { 
                  status: 200,
                  headers: { 
                      'Content-Type': 'text/html'
                  }, 
                  body: content, 
              };
          }
      });
      
  4. İstemcilerin erişim belirteci ile hizmet bağlantısı URL'sini almasına yardımcı olacak bir negotiate işlev oluşturun.

    func new -n negotiate -t HttpTrigger
    

    Not

    Bu örnekte, almak userIdiçin Microsoft Entra ID kullanıcı kimliği üst bilgisini x-ms-client-principal-name kullanacağız. Ve bu, yerel bir işlevde çalışmaz. Bunu boş yapabilir veya yerel ortamda yürüterek almak veya oluşturmak userId için başka yöntemlere değiştirebilirsiniz. Örneğin, istemcinin bir kullanıcı adı yazmasına ve hizmet bağlantısı URL'sini almak için işlevi çağırdığında negotiate gibi ?user={$username} sorguda geçirmesine izin verin. İşlevde negotiate değeriyle {query.user}ayarlayınuserId.

    • Aşağıdaki kodları güncelleştirin src/functions/negotiate ve kopyalayın.
      const { app, input } = require('@azure/functions');
      
      const connection = input.generic({
          type: 'webPubSubConnection',
          name: 'connection',
          userId: '{headers.x-ms-client-principal-name}',
          hub: 'simplechat'
      });
      
      app.http('negotiate', {
          methods: ['GET', 'POST'],
          authLevel: 'anonymous',
          extraInputs: [connection],
          handler: async (request, context) => {
              return { body: JSON.stringify(context.extraInputs.get('connection')) };
          },
      });
      
  5. hizmet aracılığıyla istemci iletileri yayınlamak için bir message işlev oluşturun.

    func new -n message -t HttpTrigger
    
    • Aşağıdaki kodları güncelleştirin src/functions/message.js ve kopyalayın.
      const { app, output, trigger } = require('@azure/functions');
      
      const wpsMsg = output.generic({
          type: 'webPubSub',
          name: 'actions',
          hub: 'simplechat',
      });
      
      const wpsTrigger = trigger.generic({
          type: 'webPubSubTrigger',
          name: 'request',
          hub: 'simplechat',
          eventName: 'message',
          eventType: 'user'
      });
      
      app.generic('message', {
          trigger: wpsTrigger,
          extraOutputs: [wpsMsg],
          handler: async (request, context) => {
              context.extraOutputs.set(wpsMsg, [{
                  "actionName": "sendToAll",
                  "data": `[${context.triggerMetadata.connectionContext.userId}] ${request.data}`,
                  "dataType": request.dataType
              }]);
      
              return {
                  data: "[SYSTEM] ack.",
                  dataType: "text",
              };
          }
      });
      
  6. Proje kök klasörüne istemci tek sayfasını index.html ekleyin ve içeriği kopyalayın.

    <html>
      <body>
        <h1>Azure Web PubSub Serverless Chat App</h1>
        <div id="login"></div>
        <p></p>
        <input id="message" placeholder="Type to chat..." />
        <div id="messages"></div>
        <script>
          (async function () {
            let authenticated = window.location.href.includes(
              "?authenticated=true"
            );
            if (!authenticated) {
              // auth
              let login = document.querySelector("#login");
              let link = document.createElement("a");
              link.href = `${window.location.origin}/.auth/login/aad?post_login_redirect_url=/api/index?authenticated=true`;
              link.text = "login";
              login.appendChild(link);
            } else {
              // negotiate
              let messages = document.querySelector("#messages");
              let res = await fetch(`${window.location.origin}/api/negotiate`, {
                credentials: "include",
              });
              let url = await res.json();
              // connect
              let ws = new WebSocket(url.url);
              ws.onopen = () => console.log("connected");
              ws.onmessage = (event) => {
                let m = document.createElement("p");
                m.innerText = event.data;
                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>
    

Azure İşlev Uygulamasını Oluşturma ve Dağıtma

İşlev kodunuzu Azure'a dağıtabilmeniz için önce üç kaynak oluşturmanız gerekir:

  • İlgili kaynaklar için mantıksal bir kapsayıcı olan kaynak grubu.
  • İşlevleriniz hakkındaki durumu ve diğer bilgileri korumak için kullanılan bir depolama hesabı.
  • İşlev kodunuzu yürütmek için ortam sağlayan bir işlev uygulaması. İşlev uygulaması yerel işlev projenize eşler ve kaynakların daha kolay yönetilmesi, dağıtılması ve paylaşılması için işlevleri mantıksal birim olarak gruplandırmanıza olanak tanır.

Bu öğeleri oluşturmak için aşağıdaki komutları kullanın.

  1. Henüz yapmadıysanız Azure'da oturum açın:

    az login
    
  2. Kaynak grubu oluşturun veya Azure Web PubSub hizmetinden birini yeniden kullanarak atlayabilirsiniz:

    az group create -n WebPubSubFunction -l <REGION>
    
  3. Kaynak grubunuz ve bölgenizde genel amaçlı bir depolama hesabı oluşturun:

    az storage account create -n <STORAGE_NAME> -l <REGION> -g WebPubSubFunction
    
  4. Azure'da işlev uygulamasını oluşturun:

    az functionapp create --resource-group WebPubSubFunction --consumption-plan-location <REGION> --runtime node --runtime-version 18 --functions-version 4 --name <FUNCIONAPP_NAME> --storage-account <STORAGE_NAME>
    

    Not

    Parametreyi desteklenen değere ayarlamak --runtime-version için Azure İşlevleri çalışma zamanı sürümleri belgelerine bakın.

  5. İşlev projesini Azure'a dağıtma:

    İşlev uygulamanızı Azure'da başarıyla oluşturduktan sonra, artık func azure functionapp publish komutunu kullanarak yerel işlevler projenizi dağıtmaya hazır olursunuz.

    func azure functionapp publish <FUNCIONAPP_NAME>
    
  6. İşlev uygulaması için'i WebPubSubConnectionString yapılandırın:

    İlk olarak, Azure Portal'dan Web PubSub kaynağınızı bulun ve Anahtarlar'ın altındaki bağlantı dizesi kopyalayın. Ardından Azure Portal -Ayarlar ->>Yapılandırma'da İşlev Uygulaması ayarları'na gidin. Uygulama ayarları'nın altına ad eşittir WebPubSubConnectionString ve değeri Web PubSub kaynağınız bağlantı dizesi olan yeni bir öğe ekleyin.

Web PubSub hizmetini yapılandırma Event Handler

Bu örnekte, yukarı akış isteklerini dinlemek için kullanıyoruz WebPubSubTrigger . Bu nedenle Web PubSub'un hedef istemci istekleri göndermek için işlevin uç nokta bilgilerini bilmesi gerekir. Azure İşlev Uygulaması, uzantıya özgü web kancası yöntemleriyle ilgili güvenlik için bir sistem anahtarı gerektirir. İşlev Uygulamasını işlevlerle message dağıttıktan sonraki önceki adımda sistem anahtarını alacağız.

Azure portalı> - İşlev Uygulaması kaynağınızı bulma ->Uygulama anahtarları -Sistem anahtarları ->>webpubsub_extension bölümüne gidin. değerini olarak <APP_KEY>kopyalayın.

İşlev sistemi anahtarlarını alma seçeneğinin ekran görüntüsü.

Azure Web PubSub hizmetinde ayarlayın Event Handler . Azure portalı - Web PubSub kaynağınızı bulma ->Ayarlar'a> gidin. Kullanımda olan tek işleve eşleyecek yeni bir hub ayarları ekleyin. ve <APP_KEY> değerini <FUNCTIONAPP_NAME> sizinkiyle değiştirin.

  • Hub Adı: simplechat
  • URL Şablonu: https://< FUNCTIONAPP_NAME.azurewebsites.net/runtime/webhooks/webpubsub?code>=<APP_KEY>
  • Kullanıcı Olay Düzeni: *
  • Sistem Olayları: -(Bu örnekte yapılandırılması gerekmez)

Olay işleyicisini ayarlama işleminin ekran görüntüsü.

İstemci kimlik doğrulamasını etkinleştirmek için yapılandırma

Azure portalı - İşlev Uygulaması kaynağınızı bulma ->Kimlik Doğrulaması'na gidin.> Add identity provider’a tıklayın. Kimlik doğrulamasına yeniden yönlendirmeden önce istemci dizini sayfanızın anonim kullanıcılar tarafından ziyaret edilebilmesi için App Service kimlik doğrulama ayarlarını Kimliği doğrulanmamış erişime izin ver olarak ayarlayın. Daha sonra Kaydet'i seçin.

Burada, işlevinde olduğu gibi userId kullanan x-ms-client-principal-name sağlayıcıyı tanımlamayı negotiate seçiyoruzMicrosoft. Ayrıca, bağlantıları izleyen diğer kimlik sağlayıcılarını yapılandırabilir ve işlevdeki negotiate değeri buna göre güncelleştirmeyi userId unutmayın.

Uygulamayı deneyin

Artık işlev uygulamanızdan sayfanızı test edebilirsiniz: https://<FUNCTIONAPP_NAME>.azurewebsites.net/api/index. Bkz. anlık görüntü.

  1. Kendiniz kimlik doğrulaması yapmak için tıklayın login .
  2. Sohbet etmek için giriş kutusuna ileti yazın.

İleti işlevinde, çağıranın iletisini tüm istemcilere yayınlar ve çağıranı iletisiyle [SYSTEM] ackdöndürüriz. Bu nedenle örnek sohbet anlık görüntüsünde ilk dört iletinin geçerli istemciden, son iki iletinin ise başka bir istemciden olduğunu anlayabiliriz.

Sohbet örneğinin ekran görüntüsü.

Kaynakları temizleme

Bu uygulamayı kullanmaya devam etmeyecekseniz, ücret ödememek için aşağıdaki adımları izleyerek bu belge tarafından oluşturulan tüm kaynakları silin:

  1. Azure portalında, en solda bulunan Kaynak grupları’nı ve ardından oluşturduğunuz kaynak grubunu seçin. Bunun yerine, kaynak grubunu adına göre bulmak için arama kutusunu kullanabilirsiniz.

  2. Açılan pencerede kaynak grubunu seçin ve ardından Kaynak grubunu sil'i seçin.

  3. Yeni pencerede, silinecek kaynak grubunun adını yazın ve sil'i seçin.

Sonraki adımlar

Bu hızlı başlangıçta sunucusuz sohbet uygulamasını çalıştırmayı öğrendiniz. Artık kendi uygulamanızı oluşturmaya başlayabilirsiniz.