Tutorial: Membuat aplikasi obrolan real time tanpa server dengan layanan Azure Functions dan Azure Web PubSub

Layanan Azure Web PubSub membantu Anda membangun aplikasi web olahpesan real time menggunakan WebSocket dan pola terbitkan-berlangganan dengan mudah. Azure Functions adalah platform tanpa server yang memungkinkan Anda menjalankan kode Anda tanpa mengelola infrastruktur apa pun. Dalam tutorial ini, Anda mempelajari cara menggunakan layanan Azure Web PubSub dan Azure Functions untuk membangun aplikasi tanpa server dengan olahpesan real time dan pola terbitkan-berlangganan.

Dalam tutorial ini, Anda akan mempelajari cara:

  • Membangun aplikasi obrolan real time tanpa server
  • Menangani pengikatan fungsi dan pengikatan output Web PubSub
  • Menyebarkan fungsi ke Aplikasi Azure Function
  • Mengonfigurasi Autentikasi Azure
  • Mengonfigurasi Web PubSub Event Handler untuk merutekan peristiwa dan pesan ke aplikasi

Prasyarat

Jika Anda tidak memiliki Langganan Azure, buat Akun gratis Azure sebelum memulai.

Masuk ke Azure

Masuk ke portal Microsoft Azure di https://portal.azure.com/ dengan akun Azure Anda.

Membuat instans layanan Azure Web PubSub

Aplikasi Anda akan terhubung ke instans layanan Web PubSub di Azure.

  1. Pilih tombol Baru yang ditemukan di sudut kiri atas portal Microsoft Azure. Di layar Baru, ketik Web PubSub di kotak pencarian dan tekan enter. (Anda juga dapat mencari Azure Web PubSub dari kategori Web.)

    Cuplikan layar pencarian Azure Web PubSub di portal.

  2. Pilih Web PubSub dari hasil pencarian, lalu pilih Buat.

  3. Masukkan pengaturan berikut.

    Pengaturan Nilai yang disarankan Deskripsi
    Nama sumber daya Nama unik secara global Nama unik global yang mengidentifikasi instans layanan Web PubSub baru Anda. Karakter yang valid adalah a-z, A-Z, 0-9, dan -.
    Langganan Langganan Anda Langganan Azure tempat instans layanan Web PubSub baru ini dibuat.
    Grup Sumber Daya myResourceGroup Nama untuk grup sumber daya baru untuk membuat instans layanan Web PubSub Anda.
    Location AS Barat Pilih wilayah di dekat Anda.
    Tingkat harga Gratis Anda dapat mencoba layanan Azure Web PubSub secara gratis terlebih dahulu. Pelajari lebih lanjut tingkat harga layanan Azure Web PubSub
    Jumlah unit - Jumlah unit menentukan berapa banyak koneksi yang dapat diterima instans layanan Web PubSub Anda. Setiap unit mendukung paling banyak 1.000 koneksi bersamaan. Ini hanya dapat dikonfigurasi dalam tingkat Standar.

    Cuplikan layar pembuatan instans Azure Web PubSub di portal.

  4. Pilih Buat untuk mulai menyebarkan instans layanan Web PubSub.

Membuat fungsi

  1. Pastikan Anda telah menginstal Azure Functions Core Tools. Dan kemudian buat direktori kosong untuk proyek. Jalankan perintah di dalam direktori kerja ini.

    func init --worker-runtime javascript --model V4
    
  2. Pasang Microsoft.Azure.WebJobs.Extensions.WebPubSub.

    Konfirmasi dan perbarui host.jsonekstensiBundle ke versi 4.* atau yang lebih baru untuk mendapatkan dukungan Web PubSub.

    {
      "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[4.*, 5.0.0)"
      }
    }
    
  3. Buat fungsi index untuk membaca dan menghosting halaman web statis untuk klien.

    func new -n index -t HttpTrigger
    
    • Perbarui src/functions/index.js dan salin kode berikut.
      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. Buat fungsi negotiate untuk membantu klien mendapatkan url koneksi layanan dengan token akses.

    func new -n negotiate -t HttpTrigger
    

    Catatan

    Dalam sampel ini, kami menggunakan header x-ms-client-principal-name identitas pengguna ID Microsoft Entra untuk mengambil userId. Dan hal ini tidak akan bekerja dalam fungsi lokal. Anda dapat membuatnya kosong atau beralih ke cara lain untuk mendapatkan atau menghasilkan userId saat melakukan pemutaran secara lokal. Misalnya, biarkan klien mengetikkan nama pengguna dan meneruskannya dalam kueri seperti ?user={$username} saat fungsi panggilan negotiate untuk mendapatkan url koneksi layanan. Dan dalam fungsi negotiate, tetapkan userId dengan nilai {query.user}.

    • Perbarui src/functions/negotiate dan salin kode berikut.
      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. Buat fungsi message untuk menyiarkan pesan klien melalui layanan.

    func new -n message -t HttpTrigger
    
    • Perbarui src/functions/message.js dan salin kode berikut.
      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. Tambahkan halaman index.html tunggal klien di folder akar proyek dan salin konten.

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

Membuat dan Menyebarkan Aplikasi Fungsi Azure

Sebelum dapat menyebarkan kode fungsi ke Azure, Anda perlu membuat tiga sumber daya:

  • Grup sumber daya, yang merupakan kontainer logis untuk sumber daya terkait.
  • Akun penyimpanan, yang digunakan untuk mempertahankan status dan informasi lain tentang fungsi Anda.
  • Aplikasi fungsi, menyediakan lingkungan untuk menjalankan kode fungsi Anda. Aplikasi fungsi memetakan ke proyek fungsi lokal Anda dan memungkinkan Anda mengelompokkan fungsi sebagai unit logis untuk pengelolaan, penyebaran, dan berbagi sumber daya yang lebih mudah.

Gunakan perintah berikut untuk membuat item ini.

  1. Jika Anda belum melakukannya, masuk ke Azure:

    az login
    
  2. Buat grup sumber daya atau Anda dapat melompati dengan menggunakan kembali salah satu layanan Azure Web PubSub:

    az group create -n WebPubSubFunction -l <REGION>
    
  3. Buat akun penyimpanan tujuan umum di grup sumber daya dan wilayah Anda:

    az storage account create -n <STORAGE_NAME> -l <REGION> -g WebPubSubFunction
    
  4. Buat aplikasi fungsi di Azure:

    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>
    

    Catatan

    Periksa dokumentasi versi runtime Azure Functions untuk mengatur --runtime-version parameter ke nilai yang didukung.

  5. Menyebarkan proyek fungsi ke Azure:

    Setelah berhasil membuat aplikasi fungsi di Azure, Anda sekarang siap untuk menyebarkan proyek fungsi lokal anda dengan menggunakan perintah penerbitan func azure functionapp.

    func azure functionapp publish <FUNCIONAPP_NAME>
    
  6. Mengonfigurasi WebPubSubConnectionString untuk aplikasi fungsi:

    Pertama, temukan sumber daya Web PubSub Anda dari Portal Microsoft Azure dan salin string koneksi di bagian Kunci. Kemudian, navigasikan ke pengaturan Aplikasi Fungsi di Portal Microsoft Azure ->Pengaturan ->Configuration. Dan tambahkan item baru di Pengaturan aplikasi, dengan nama setara dengan WebPubSubConnectionString dan nilai adalah string koneksi sumber daya Web PubSub Anda.

Mengonfigurasi Event Handler layanan Web PubSub

Dalam sampel ini, kami menggunakan WebPubSubTrigger untuk mendengarkan permintaan upstram layanan. Jadi, Web PubSub perlu mengetahui informasi titik akhir fungsi untuk mengirim permintaan klien target. Dan Azure Function App memerlukan kunci sistem untuk keamanan mengenai metode webhook khusus ekstensi. Pada langkah sebelumnya setelah menyebarkan Function App dengan fungsi message, kita bisa mendapatkan kunci sistem.

Buka portal Azure -> Temukan sumber daya Aplikasi Fungsi Anda ->Kunci aplikasi ->Kunci sistem ->webpubsub_extension. Salin nilainya sebagai <APP_KEY>.

Cuplikan layar dapatkan kunci sistem fungsi.

Lihat Event Handler di layanan Azure Web PubSub. Buka portal Azure -> Temukan sumber daya Web PubSub Anda ->Pengaturan. Tambahkan pemetaan pengaturan hub baru ke satu fungsi yang digunakan. Ganti <FUNCTIONAPP_NAME> dan <APP_KEY> dengan milik Anda.

  • Nama Hub: simplechat
  • Templat URL: https://< FUNCTIONAPP_NAME.azurewebsites.net/runtime/webhooks/webpubsub?code>=<APP_KEY>
  • Pola Kejadian Pengguna: *
  • Kejadian Sistem: -(Tidak perlu dikonfigurasi dalam sampel ini)

Cuplikan layar pengaturan handler peristiwa.

Mengonfigurasi untuk mengaktifkan autentikasi klien

Buka portal Azure -> Temukan sumber daya Aplikasi Fungsi Anda ->Autentikasi. Klik Add identity provider. Atur pengaturan autentikasi App Service ke Izinkan akses yang tidak diautentikasi, sehingga halaman indeks klien Anda dapat dikunjungi oleh pengguna anonim sebelum dialihkan untuk mengautentikasi. Kemudian Simpan.

Di sini kita memilih Microsoft sebagai penyedia identifikasi, yang menggunakan x-ms-client-principal-name seperti userId dalam negotiate fungsi. Selain itu, Anda dapat mengonfigurasi penyedia identitas lain mengikuti tautan, dan jangan lupa memperbarui userId nilai dalam negotiate fungsi yang sesuai.

Coba aplikasi

Sekarang Anda dapat menguji halaman Anda dari aplikasi fungsi Anda: https://<FUNCTIONAPP_NAME>.azurewebsites.net/api/index. Lihat rekam jepret.

  1. Klik login untuk mengautentikasi diri Anda sendiri.
  2. Ketikkan pesan dalam kotak input untuk mengobrol.

Dalam fungsi pesan, kami menyiarkan pesan penelepon ke semua klien dan mengembalikan pemanggil dengan pesan [SYSTEM] ack. Jadi kita dapat mengetahui dalam sampel rekam jepret obrolan, empat pesan pertama berasal dari klien saat ini dan dua pesan terakhir berasal dari klien lain.

Cuplikan layar sampel obrolan.

Membersihkan sumber daya

Jika Anda tidak akan terus menggunakan aplikasi ini, hapus semua sumber daya yang dibuat oleh dokumen ini dengan langkah-langkah berikut agar Anda tidak dikenakan biaya apa pun:

  1. Di portal Azure, pilih Grup sumber daya di paling kiri, lalu pilih grup sumber daya yang Anda buat. Atau Anda dapat menggunakan kotak pencarian untuk menemukan grup sumber daya berdasarkan namanya.

  2. Di jendela yang terbuka, pilih grup sumber daya, lalu pilih Hapus grup sumber daya.

  3. Di jendela baru, ketik nama grup sumber daya untuk dihapus, lalu pilih Hapus.

Langkah berikutnya

Dalam mulai cepat ini, Anda mempelajari cara menjalankan aplikasi obrolan tanpa server. Sekarang, Anda bisa mulai membangun aplikasi Anda sendiri.