Cara: Menggunakan fitur audiens di Fluid Framework

Dalam tutorial ini, Anda akan mempelajari tentang menggunakan Audiens Fluid Framework dengan React untuk membuat demonstrasi visual pengguna yang terhubung ke kontainer. Objek audiens menyimpan informasi yang terkait dengan semua pengguna yang terhubung ke kontainer. Dalam contoh ini, pustaka Klien Azure akan digunakan untuk membuat kontainer dan audiens.

Gambar berikut menunjukkan tombol ID dan bidang input ID kontainer. Membiarkan bidang ID kontainer kosong dan mengklik tombol ID pengguna akan membuat kontainer baru dan bergabung sebagai pengguna yang dipilih. Atau, pengguna akhir dapat memasukkan ID kontainer dan memilih ID pengguna untuk bergabung dengan kontainer yang ada sebagai pengguna yang dipilih.

A screenshot of a browser with buttons for selecting a user.

Gambar berikutnya memperlihatkan beberapa pengguna yang tersambung ke kontainer yang diwakili oleh kotak. Kotak yang diuraikan dengan warna biru mewakili pengguna yang melihat klien sementara kotak yang diuraikan dalam warna hitam mewakili pengguna lain yang terhubung. Saat pengguna baru melampirkan ke kontainer dengan ID unik, jumlah kotak akan meningkat.

A screenshot of a browser showing information for four different container users.

Catatan

Tutorial ini mengasumsikan bahwa Anda terbiasa dengan Gambaran Umum Kerangka Kerja Fluid dan bahwa Anda telah menyelesaikan Mulai Cepat. Anda juga harus terbiasa dengan dasar-dasar React, membuat proyek React, dan React Hooks.

Membuat proyek

  1. Buka Prompt Perintah dan navigasi ke folder induk tempat Anda ingin membuat proyek; misalnya, C:\My Fluid Projects.

  2. Jalankan perintah berikut pada prompt. (Perhatikan bahwa CLI adalah npx, bukan npm. Ini diinstal ketika Anda menginstal Node.js.)

    npx create-react-app fluid-audience-tutorial
    
  3. Proyek dibuat dalam subfolder bernama fluid-audience-tutorial. Navigasikan ke dalamnya dengan perintah cd fluid-audience-tutorial.

  4. Proyek ini menggunakan pustaka Fluid berikut:

    Pustaka Deskripsi
    fluid-framework Berisi struktur data terdistribusi SharedMap yang menyinkronkan data di seluruh klien.
    @fluidframework/azure-client Menentukan koneksi ke server layanan Fluid dan menentukan skema awal untuk kontainer Fluid.
    @fluidframework/test-client-utils Menentukan InsecureTokenProvider yang diperlukan untuk membuat koneksi ke Fluid Service.

    Jalankan perintah berikut untuk menginstal pustaka.

    npm install @fluidframework/azure-client @fluidframework/test-client-utils fluid-framework
    

Kode proyek

Menyiapkan variabel status dan tampilan komponen

  1. Buka file \src\App.js di editor kode. Hapus semua pernyataan default import . Kemudian hapus semua markup dari return pernyataan. Kemudian tambahkan pernyataan impor untuk komponen dan kait React. Perhatikan bahwa kami akan menerapkan komponen AudienceDisplay dan UserIdSelection yang diimpor di langkah selanjutnya. File akan terlihat seperti berikut:

        import { useState, useCallback } from "react";
        import { AudienceDisplay } from "./AudienceDisplay";
        import { UserIdSelection } from "./UserIdSelection";
    
        export const App = () => {
        // TODO 1: Define state variables to handle view changes and user input
        return (
        // TODO 2: Return view components
        );
        }
    
  2. Ganti TODO 1 dengan kode berikut. Kode ini menginisialisasi variabel status lokal yang akan digunakan dalam aplikasi. Nilai displayAudience menentukan apakah kita merender komponen AudienceDisplay atau komponen UserIdSelection (lihat TODO 2). Nilainya userId adalah pengidentifikasi pengguna untuk terhubung ke kontainer dengan dan containerId nilainya adalah kontainer yang akan dimuat. Fungsi handleSelectUser dan handleContainerNotFound diteruskan sebagai panggilan balik ke dua tampilan dan mengelola transisi status. handleSelectUser dipanggil saat mencoba membuat/memuat kontainer. handleContainerNotFound dipanggil saat membuat/memuat kontainer gagal.

    Perhatikan, nilai userId dan containerId akan berasal dari komponen UserIdSelection melalui handleSelectUser fungsi .

        const [displayAudience, setDisplayAudience] = useState(false);
        const [userId, setUserId] = useState();
        const [containerId, setContainerId] = useState();
    
        const handleSelectUser = useCallback((userId, containerId) => {
        setDisplayAudience(true)
        setUserId(userId);
        setContainerId(containerId);
        }, [displayAudience, userId, containerId]);
    
        const handleContainerNotFound = useCallback(() => {
        setDisplayAudience(false)
        }, [setDisplayAudience]);
    
  3. Ganti TODO 2 dengan kode berikut. Seperti yang dinyatakan displayAudience di atas, variabel akan menentukan apakah kita merender komponen AudienceDisplay atau komponen UserIdSelection . Selain itu, fungsi untuk memperbarui variabel status diteruskan ke komponen sebagai properti.

        (displayAudience) ?
        <AudienceDisplay userId={userId} containerId={containerId} onContainerNotFound={handleContainerNotFound}/> :
        <UserIdSelection onSelectUser={handleSelectUser}/>
    

Menyiapkan komponen AudienceDisplay

  1. Buat dan buka file \src\AudienceDisplay.js di editor kode. Tambahkan pernyataan import berikut:

        import { useEffect, useState } from "react";
        import { SharedMap } from "fluid-framework";
        import { AzureClient } from "@fluidframework/azure-client";
        import { InsecureTokenProvider } from "@fluidframework/test-client-utils";
    

    Perhatikan bahwa objek yang diimpor dari pustaka Fluid Framework diperlukan untuk menentukan pengguna dan kontainer. Dalam langkah-langkah berikut, AzureClient dan InsecureTokenProvider akan digunakan untuk mengonfigurasi layanan klien (lihat TODO 1) sementara SharedMap akan digunakan untuk mengonfigurasi containerSchema yang diperlukan untuk membuat kontainer (lihat TODO 2).

  2. Tambahkan komponen fungsi dan fungsi pembantu berikut:

        const tryGetAudienceObject = async (userId, userName, containerId) => {
        // TODO 1: Create container and return audience object
        }
    
        export const AudienceDisplay = (props) => {
        //TODO 2: Configure user ID, user name, and state variables
        //TODO 3: Set state variables and set event listener on component mount
        //TODO 4: Return list view
        }
    
        const AudienceList = (data) => {
        //TODO 5: Append view elements to list array for each member
        //TODO 6: Return list of member elements
        }
    

    Perhatikan bahwa AudienceDisplay dan AudienceList adalah komponen fungsi yang menangani mendapatkan dan merender data audiens saat tryGetAudienceObject metode menangani pembuatan kontainer dan layanan audiens.

Mendapatkan kontainer dan audiens

Anda dapat menggunakan fungsi pembantu untuk mendapatkan data Fluid, dari objek Audiens, ke lapisan tampilan (status React). Metode tryGetAudienceObject ini dipanggil ketika komponen tampilan dimuat setelah ID pengguna dipilih. Nilai yang dikembalikan ditetapkan ke properti status React.

  1. Ganti TODO 1 dengan kode berikut. Perhatikan bahwa nilai untuk userIduserNamecontainerId akan diteruskan dari komponen Aplikasi. Jika tidak containerIdada , kontainer baru dibuat. Selain itu, perhatikan bahwa containerId disimpan di hash URL. Pengguna yang memasukkan sesi dari browser baru dapat menyalin URL dari browser sesi yang ada atau menavigasi ke localhost:3000 dan memasukkan ID kontainer secara manual. Dengan implementasi ini, kami ingin membungkus getContainer panggilan dalam tangkapan percobaan dalam kasus bahwa pengguna memasukkan ID kontainer yang tidak ada. Kunjungi dokumentasi Kontainer untuk informasi selengkapnya.

        const userConfig = {
            id: userId,
            name: userName,
            additionalDetails: {
                email: userName.replace(/\s/g, "") + "@example.com",
                date: new Date().toLocaleDateString("en-US"),
            },
        };
    
        const serviceConfig = {
            connection: {
                type: "local",
                tokenProvider: new InsecureTokenProvider("", userConfig),
                endpoint: "http://localhost:7070",
            },
        };
    
        const client = new AzureClient(serviceConfig);
    
        const containerSchema = {
            initialObjects: { myMap: SharedMap },
        };
    
        let container;
        let services;
        if (!containerId) {
            ({ container, services } = await client.createContainer(containerSchema));
            const id = await container.attach();
            location.hash = id;
        } else {
            try {
                ({ container, services } = await client.getContainer(containerId, containerSchema));
            } catch (e) {
                return;
            }
        }
        return services.audience;
    

Mendapatkan audiens pada pemasangan komponen

Sekarang setelah kita menentukan cara mendapatkan audiens Fluid, kita perlu memberi tahu React untuk memanggil tryGetAudienceObject saat komponen Tampilan Audiens dipasang.

  1. Ganti TODO 2 dengan kode berikut. Perhatikan bahwa ID pengguna akan berasal dari komponen induk sebagai user1user2 atau random. Jika ID digunakan randomMath.random() untuk menghasilkan angka acak sebagai ID. Selain itu, nama akan dipetakan ke pengguna berdasarkan ID mereka seperti yang ditentukan dalam userNameList. Terakhir, kami menentukan variabel status yang akan menyimpan anggota yang terhubung serta pengguna saat ini. fluidMembers akan menyimpan daftar semua anggota yang terhubung ke kontainer sedangkan currentMember akan berisi objek anggota yang mewakili pengguna saat ini yang melihat konteks browser.

        const userId = props.userId == "random" ? Math.random() : props.userId;
        const userNameList = {
        "user1" : "User One",
        "user2" : "User Two",
        "random" : "Random User"
        };
        const userName = userNameList[props.userId];
    
        const [fluidMembers, setFluidMembers] = useState();
        const [currentMember, setCurrentMember] = useState();
    
  2. Ganti TODO 3 dengan kode berikut. Ini akan memanggil tryGetAudienceObject ketika komponen dipasang dan mengatur anggota audiens yang dikembalikan ke fluidMembers dan currentMember. Catatan, kita memeriksa apakah objek audiens dikembalikan jika pengguna memasukkan containerId yang tidak ada dan kita perlu mengembalikannya ke tampilan UserIdSelection (props.onContainerNotFound() akan menangani peralihan tampilan). Juga, adalah praktik yang baik untuk membatalkan pendaftaran penanganan aktivitas ketika komponen React melepas dengan mengembalikan audience.off.

        useEffect(() => {
        tryGetAudienceObject(userId, userName, props.containerId).then(audience => {
            if(!audience) {
            props.onContainerNotFound();
            alert("error: container id not found.");
            return;
            }
    
            const updateMembers = () => {
            setFluidMembers(audience.getMembers());
            setCurrentMember(audience.getMyself());
            }
    
            updateMembers();
    
            audience.on("membersChanged", updateMembers);
    
            return () => { audience.off("membersChanged", updateMembers) };
        });
        }, []);
    
  3. Ganti TODO 4 dengan kode berikut. Perhatikan, jika fluidMembers atau currentMember belum diinisialisasi, layar kosong akan dirender. Komponen AudienceList akan merender data anggota dengan gaya (akan diimplementasikan di bagian berikutnya).

        if (!fluidMembers || !currentMember) return (<div/>);
    
        return (
            <AudienceList fluidMembers={fluidMembers} currentMember={currentMember}/>
        )
    

    Catatan

    transisi Koneksi ion dapat mengakibatkan jendela waktu pendek di mana getMyself mengembalikan undefined. Ini karena koneksi klien saat ini belum akan ditambahkan ke audiens, sehingga ID koneksi yang cocok tidak dapat ditemukan. Untuk mencegah React merender halaman tanpa anggota audiens, kami menambahkan pendengar untuk memanggil updateMembers .membersChanged Ini berfungsi karena audiens layanan memancarkan membersChanged peristiwa saat kontainer terhubung.

Membuat tampilan

  1. Ganti TODO 5 dengan kode berikut. Perhatikan bahwa kami merender komponen daftar untuk setiap anggota yang diteruskan dari komponen AudienceDisplay . Untuk setiap anggota, pertama-tama kami membandingkan currentMember.userId dengan member.userId memeriksa apakah anggota isSelftersebut . Dengan cara ini, kita dapat membedakan pengguna klien dari pengguna lain dan menampilkan komponen dengan warna yang berbeda. Kami kemudian mendorong komponen daftar ke list array. Setiap komponen akan menampilkan data anggota seperti userIduserName dan additionalDetails.

        const currentMember = data.currentMember;
        const fluidMembers = data.fluidMembers;
    
        const list = [];
        fluidMembers.forEach((member, key) => {
            const isSelf = (member.userId === currentMember.userId);
            const outlineColor = isSelf ? 'blue' : 'black';
    
            list.push(
            <div style={{
                padding: '1rem',
                margin: '1rem',
                display: 'flex',
                outline: 'solid',
                flexDirection: 'column',
                maxWidth: '25%',
                outlineColor
            }} key={key}>
                <div style={{fontWeight: 'bold'}}>Name</div>
                <div>
                    {member.userName}
                </div>
                <div style={{fontWeight: 'bold'}}>ID</div>
                <div>
                    {member.userId}
                </div>
                <div style={{fontWeight: 'bold'}}>Connections</div>
                {
                    member.connections.map((data, key) => {
                        return (<div key={key}>{data.id}</div>);
                    })
                }
                <div style={{fontWeight: 'bold'}}>Additional Details</div>
                { JSON.stringify(member.additionalDetails, null, '\t') }
            </div>
            );
        });
    
  2. Ganti TODO 6 dengan kode berikut. Ini akan merender semua elemen anggota yang kami dorong ke list dalam array.

        return (
            <div>
                {list}
            </div>
        );
    

Menyiapkan komponen UserIdSelection

  1. Buat dan buka file \src\UserIdSelection.js di editor kode. Komponen ini akan menyertakan tombol ID pengguna dan bidang input ID kontainer yang memungkinkan pengguna akhir untuk memilih ID pengguna dan sesi kolaboratif mereka. Tambahkan pernyataan dan import komponen fungsi berikut:

    import { useState } from 'react';
    
    export const UserIdSelection = (props) => {
        // TODO 1: Define styles and handle user inputs
        return (
        // TODO 2: Return view components
        );
    }
    
  2. Ganti TODO 1 dengan kode berikut. Perhatikan bahwa onSelectUser fungsi akan memperbarui variabel status di komponen Aplikasi induk dan meminta perubahan tampilan. Metode handleSubmit ini dipicu oleh elemen tombol yang akan diimplementasikan di TODO 2. Selain itu handleChange , metode ini digunakan untuk memperbarui containerId variabel status. Metode ini akan dipanggil dari pendengar peristiwa elemen input yang diimplementasikan di TODO 2. Perhatikan juga bahwa kami memperbarui containerId mendapatkan nilai dari elemen HTML dengan id containerIdInput (didefinisikan dalam TODO 2).

        const selectionStyle = {
        marginTop: '2rem',
        marginRight: '2rem',
        width: '150px',
        height: '30px',
        };
    
        const [containerId, setContainerId] = (location.hash.substring(1));
    
        const handleSubmit = (userId) => {
        props.onSelectUser(userId, containerId);
        }
    
        const handleChange = () => {
        setContainerId(document.getElementById("containerIdInput").value);
        };
    
  3. Ganti TODO 2 dengan kode berikut. Ini akan merender tombol ID pengguna serta bidang input ID kontainer.

        <div style={{display: 'flex', flexDirection:'column'}}>
        <div style={{marginBottom: '2rem'}}>
            Enter Container Id:
            <input type="text" id="containerIdInput" value={containerId} onChange={() => handleChange()} style={{marginLeft: '2rem'}}></input>
        </div>
        {
            (containerId) ?
            (<div style={{}}>Select a User to join container ID: {containerId} as the user</div>)
            : (<div style={{}}>Select a User to create a new container and join as the selected user</div>)
        }
        <nav>
            <button type="submit" style={selectionStyle} onClick={() => handleSubmit("user1")}>User 1</button>
            <button type="submit" style={selectionStyle} onClick={() => handleSubmit("user2")}>User 2</button>
            <button type="submit" style={selectionStyle} onClick={() => handleSubmit("random")}>Random User</button>
        </nav>
        </div>
    

Mulai server Fluid dan jalankan aplikasi

Catatan

Untuk mencocokkan cara penggunaan lainnya, bagian ini menggunakan npx dan npm perintah untuk memulai server Fluid. Namun, kode dalam artikel ini juga dapat berjalan terhadap server Azure Fluid Relay. Untuk informasi selengkapnya, lihat Cara: Menyediakan layanan Azure Fluid Relay dan Cara: Koneksi ke layanan Azure Fluid Relay

Di Prompt Perintah, jalankan perintah berikut untuk memulai layanan Fluid.

npx @fluidframework/azure-local-service@latest

Buka Prompt Perintah baru dan navigasi ke akar proyek; misalnya, C:/My Fluid Projects/fluid-audience-tutorial. Mulai server aplikasi dengan perintah berikut. Aplikasi terbuka di browser. Proses ini memerlukan waktu beberapa menit.

npm run start

Navigasikan ke localhost:3000 pada tab browser untuk melihat aplikasi yang sedang berjalan. Untuk membuat kontainer baru, pilih tombol ID pengguna sambil membiarkan input ID kontainer kosong. Untuk mensimulasikan pengguna baru yang bergabung dengan sesi kontainer, buka tab browser baru dan navigasi ke localhost:3000. Kali ini, masukkan nilai ID kontainer yang dapat ditemukan dari url tab browser pertama yang melanjutkan http://localhost:3000/#.

Catatan

Anda mungkin perlu menginstal dependensi tambahan untuk membuat demo ini kompatibel dengan Webpack 5. Jika Anda menerima kesalahan kompilasi yang terkait dengan paket "buffer" atau "url", silakan jalankan npm install -D buffer url dan coba lagi. Ini akan diselesaikan dalam rilis Fluid Framework di masa mendatang.

Langkah berikutnya

  • Coba perluas demo dengan lebih banyak pasangan kunci/nilai di additionalDetails bidang di userConfig.
  • Pertimbangkan untuk mengintegrasikan audiens ke dalam aplikasi kolaboratif yang menggunakan struktur data terdistribusi seperti SharedMap atau SharedString.
  • Pelajari selengkapnya tentang Audiens.

Tip

Ketika Anda membuat perubahan pada kode, proyek akan secara otomatis dibangun ulang dan server aplikasi akan memuat ulang. Namun, jika Anda membuat perubahan pada skema kontainer, perubahan tersebut hanya akan berlaku jika Anda menutup dan menghidupkan ulang server aplikasi. Untuk melakukan ini, berikan fokus ke Prompt Perintah dan tekan Ctrl-C dua kali. Kemudian jalankan npm run start lagi.