Bagikan melalui


Tutorial - Publikasikan dan berlangganan pesan antara klien WebSocket menggunakan subprotokol

Dalam Tutorial membangun aplikasi obrolan, Anda mempelajari cara menggunakan API WebSocket untuk mengirim dan menerima data dengan Azure Web PubSub. Anda dapat melihat bahwa tidak ada protokol yang diperlukan saat klien berkomunikasi dengan layanan. Misalnya, Anda dapat mengirim semua jenis data menggunakan WebSocket.send(), dan server menerimanya apa adanya. Proses API WebSocket mudah digunakan, tetapi fungsionalitasnya terbatas. Misalnya, Anda tidak dapat menentukan nama peristiwa saat mengirim peristiwa ke server Anda, atau menerbitkan pesan ke klien lain alih-alih mengirimkannya ke server Anda. Dalam tutorial ini, Anda mempelajari cara menggunakan subprotokola untuk memperluas fungsionalitas klien.

Dalam tutorial ini, Anda akan mempelajari cara:

  • Membuat instans layanan Web PubSub
  • Menghasilkan URL lengkap untuk membuat koneksi WebSocket
  • Memublikasikan pesan antar klien WebSocket menggunakan subprotokol

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

Prasyarat

  • Penyiapan ini memerlukan CLI Azure versi 2.22.0 atau lebih tinggi. Jika menggunakan Azure Cloud Shell, versi terbaru sudah terinstal.

Membuat instans Azure Web PubSub

Buat grup sumber daya

Grup sumber daya adalah kontainer logis yang disebarkan dan dikelola oleh sumber daya Azure. Gunakan perintah az group create untuk membuat grup sumber daya bernama myResourceGroup di eastus lokasi.

az group create --name myResourceGroup --location EastUS

Membuat instans Web PubSub

Jalankan az extension add untuk menginstal atau meningkatkan ekstensi webpubsub ke versi saat ini.

az extension add --upgrade --name webpubsub

Gunakan perintah az webpubsub create Azure CLI untuk membuat Web PubSub di grup sumber daya yang telah Anda buat. Perintah berikut membuat sumber daya Web PubSub Gratis di bawah grup sumber daya myResourceGroup di EastUS:

Penting

Setiap sumber daya Web PubSub harus memiliki nama yang unik. Ganti <your-unique-resource-name> dengan nama Web PubSub Anda dalam contoh berikut.

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

Keluaran dari perintah ini menunjukkan properti sumber daya yang baru dibuat. Perhatikan dua properti yang tercantum di bawah:

  • Nama Sumber Daya: Nama yang Anda berikan untuk parameter --name di atas.
  • hostName: Dalam contoh, nama host adalah <your-unique-resource-name>.webpubsub.azure.com/.

Pada titik ini, akun Azure Anda adalah satu-satunya yang berwenang untuk melakukan operasi apa pun di sumber daya baru ini.

Mendapatkan ConnectionString untuk penggunaan di masa mendatang

Penting

String koneksi menyertakan informasi otorisasi yang diperlukan agar aplikasi Anda mengakses layanan Azure Web PubSub. Kunci akses di dalam string koneksi mirip dengan kata sandi root untuk layanan Anda. Di lingkungan produksi, selalu berhati-hatilah untuk melindungi kunci akses Anda. Gunakan Azure Key Vault untuk mengelola dan memutar kunci Anda dengan aman. Hindari mendistribusikan kunci akses ke pengguna lain, melakukan hard-coding, atau menyimpannya di mana saja dalam teks biasa yang dapat diakses orang lain. Putar kunci Anda jika Anda yakin bahwa kunci tersebut mungkin telah disusupi.

Gunakan perintah Azure CLI az webpubsub key untuk mendapatkan ConnectionString layanan. <your-unique-resource-name> Ganti tempat penampung dengan nama instans Azure Web PubSub Anda.

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

Salin string koneksi untuk digunakan nanti.

Salin Koneksi ionString yang diambil dan gunakan nanti dalam tutorial ini sebagai nilai <connection_string>.

Menyiapkan proyek

Prasyarat

Menggunakan subprotokol

Klien dapat memulai koneksi WebSocket menggunakan subprotokol tertentu. Layanan Azure Web PubSub mendukung subprotokola yang dipanggil json.webpubsub.azure.v1 untuk memberdayakan klien untuk melakukan penerbitan/berlangganan langsung melalui layanan Web PubSub alih-alih pulang pergi ke server upstream. Periksa subprotokol WebSocket JSON yang didukung Azure Web PubSub untuk detail tentang subprotokol.

Jika Anda menggunakan nama protokol lain, nama tersebut akan diabaikan oleh layanan dan passthrough ke server di sambungkan penanganan aktivitas, sehingga Anda dapat membangun protokol Anda sendiri.

Kini mari membuat aplikasi web menggunakan subprotokol json.webpubsub.azure.v1.

  1. Instal dependensi

    mkdir logstream
    cd logstream
    dotnet new web
    dotnet add package Microsoft.Extensions.Azure
    dotnet add package Azure.Messaging.WebPubSub
    
  2. Buat sisi server untuk menghosting API dan halaman web /negotiate.

    Perbarui Program.cs dengan kode di bawah ini.

    • Gunakan AddAzureClients untuk menambahkan klien layanan, dan membaca string koneksi dari konfigurasi.
    • Tambahkan app.UseStaticFiles(); sebelumnya app.Run(); untuk mendukung file statis.
    • Dan perbarui app.MapGet untuk menghasilkan token akses klien dengan permintaan /negotiate.
    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. Membuat halaman web

    Buat halaman HTML dengan konten di bawah ini dan simpan sebagai 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>                                                                
    

    Kode di atas terhubung ke layanan dan mencetak pesan apa pun yang diterima ke halaman. Perubahan utama adalah bahwa kita menentukan subprotokol saat membuat koneksi WebSocket.

  4. Menjalankan server

    Kami menggunakan alat Manajer Rahasia untuk .NET Core guna mengatur string koneksi. Jalankan perintah di bawah ini, ganti <connection_string> dengan yang diambil di langkah sebelumnya dan buka http://localhost:5000/index.html di browser:

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

    Jika Anda menggunakan Chrome, Anda dapat menekan F12 atau klik kanan ->Inspect ->Developer Tools, dan pilih tab Jaringan . Muat halaman web, dan Anda dapat melihat koneksi WebSocket dibuat. Pilih untuk memeriksa koneksi WebSocket, Anda dapat melihat pesan peristiwa di bawah connected ini diterima di klien. Anda dapat melihat bahwa Anda mendapatkan connectionId dibuat untuk klien ini.

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

Anda dapat melihat bahwa dengan bantuan subprotokol, Anda bisa mendapatkan beberapa metadata koneksi saat koneksi adalah connected.

Klien sekarang menerima pesan JSON alih-alih teks biasa. Pesan JSON berisi informasi lebih lanjut seperti jenis dan sumber pesan. Jadi Anda dapat menggunakan informasi ini untuk melakukan lebih banyak pemrosesan ke pesan (misalnya menampilkan pesan dengan gaya yang berbeda jika dari sumber yang berbeda), yang dapat Anda temukan di bagian selanjutnya.

Memublikasikan pesan dari klien

Dalam tutorial Membangun aplikasi obrolan, ketika klien mengirim pesan melalui koneksi WebSocket ke layanan Web PubSub, layanan memicu peristiwa pengguna di sisi server Anda. Dengan subprotokola, klien memiliki lebih banyak fungsi dengan mengirim pesan JSON. Misalnya, Anda dapat menerbitkan pesan langsung dari klien melalui layanan Web PubSub ke klien lain.

Ini berguna jika Anda ingin mengalirkan sejumlah besar data ke klien lain secara real time. Mari kita gunakan fitur ini untuk membangun aplikasi streaming log, yang dapat melakukan streaming log konsol ke browser secara waktu nyata.

  1. Membuat program streaming

    Membuat program stream:

    mkdir stream
    cd stream
    dotnet new console
    

    Perbarui Program.cs dengan konten berikut:

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

    Anda dapat melihat ada konsep baru "grup" di sini. Grup adalah konsep logis di hub tempat Anda dapat memublikasikan pesan ke sekelompok koneksi. Di hub, Anda dapat memiliki beberapa grup dan satu klien dapat berlangganan beberapa grup secara bersamaan. Saat menggunakan subprotokol, Anda hanya dapat memublikasikan ke grup alih-alih menyiarkan ke seluruh hub. Untuk detail tentang istilah, periksa konsep dasar.

  2. Karena kita menggunakan grup di sini, kita juga perlu memperbarui halaman web index.html untuk bergabung dengan grup saat koneksi WebSocket didirikan di panggilan balik ws.onopen.

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

    Anda dapat melihat klien bergabung ke grup dengan mengirimkan pesan dalam jenis joinGroup.

  3. Perbarui juga logika panggilan balik ws.onmessage sedikit untuk mengurai respon JSON dan mencetak pesan hanya dari grup stream sehingga bertindak sebagai printer streaming langsung.

    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. Untuk pertimbangan keamanan, secara default klien tidak dapat memublikasikan atau berlangganan grup dengan sendirinya. Jadi Anda melihat bahwa kami mengatur roles ke klien saat menghasilkan token:

    Mengatur roles saat GenerateClientAccessUri di Startup.cs seperti di bawah ini:

    service.GenerateClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" })
    
  5. Akhirnya, terapkan juga beberapa gaya ke index.html sehingga ditampilkan dengan baik.

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

Sekarang jalankan kode di bawah ini dan ketik teks apa pun dan teks ditampilkan di browser secara real time:

ls -R | dotnet run

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

Atau buat agar lebih lambat sehingga Anda dapat melihat data dialirkan ke browser secara waktu nyata:

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

Sampel kode lengkap dari tutorial ini dapat ditemukan di sini.

Langkah berikutnya

Tutorial ini memberi Anda gambaran dasar tentang cara menyambungkan ke layanan Web PubSub dan cara menerbitkan pesan ke klien yang terhubung menggunakan subprotokola.

Lihat tutorial lain untuk mempelajari lebih lanjut cara menggunakan layanan ini.