Share via


Anvisningar: Använda målgruppsfunktioner i Fluid Framework

I den här självstudien får du lära dig mer om hur du använder Fluid Framework-målgruppen med React för att skapa en visuell demonstration av användare som ansluter till en container. Målgruppsobjektet innehåller information om alla användare som är anslutna till containern. I det här exemplet används Azure-klientbiblioteket för att skapa containern och målgruppen.

Följande bild visar ID-knappar och ett indatafält för container-ID. Om du lämnar fältet för container-ID tomt och klickar på en användar-ID-knapp skapas en ny container och kopplas som vald användare. Alternativt kan slutanvändaren ange ett container-ID och välja ett användar-ID för att ansluta till en befintlig container som vald användare.

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

Nästa bild visar flera användare som är anslutna till en container som representeras av rutor. Rutan som beskrivs i blått representerar den användare som visar klienten medan rutorna som beskrivs i svart representerar de andra anslutna användarna. När nya användare ansluter till containern med unika ID:n ökar antalet rutor.

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

Kommentar

Den här självstudien förutsätter att du är bekant med Översikt över Fluid Framework och att du har slutfört snabbstarten. Du bör också känna till grunderna i React, skapa React-projekt och React Hooks.

Skapa projektet

  1. Öppna en kommandotolk och gå till den överordnade mappen där du vill skapa projektet. t.ex. C:\My Fluid Projects.

  2. Kör följande kommando i kommandotolken. (Observera att CLI är npx, inte npm. Det installerades när du installerade Node.js.)

    npx create-react-app fluid-audience-tutorial
    
  3. Projektet skapas i en undermapp med namnet fluid-audience-tutorial. Navigera till den med kommandot cd fluid-audience-tutorial.

  4. Projektet använder följande Fluid-bibliotek:

    Bibliotek beskrivning
    fluid-framework Innehåller den delade map-distribuerade datastrukturen som synkroniserar data mellan klienter.
    @fluidframework/azure-client Definierar anslutningen till en fluidtjänstserver och definierar startschemat för fluidcontainern.
    @fluidframework/test-client-utils Definierar den InsecureTokenProvider som behövs för att skapa anslutningen till en fluidtjänst.

    Kör följande kommando för att installera biblioteken.

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

Koda projektet

Konfigurera tillståndsvariabler och komponentvy

  1. Öppna filen \src\App.js i kodredigeraren. Ta bort alla standardinstruktioner import . Ta sedan bort alla markeringar från -instruktionen return . Lägg sedan till importinstruktioner för komponenter och React-krokar. Observera att vi kommer att implementera de importerade komponenterna AudienceDisplay och UserIdSelection i de senare stegen. Filen bör se ut så här:

        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. Ersätt TODO 1 med följande kod. Den här koden initierar lokala tillståndsvariabler som ska användas i programmet. Värdet displayAudience avgör om vi återger AudienceDisplay-komponenten eller UserIdSelection-komponenten (se TODO 2). Värdet userId är den användaridentifierare som ska anslutas till containern med och containerId värdet är containern som ska läsas in. Funktionerna handleSelectUser och handleContainerNotFound skickas som återanrop till de två vyerna och hanterar tillståndsövergångar. handleSelectUser anropas när du försöker skapa/läsa in en container. handleContainerNotFound anropas när det inte går att skapa/läsa in en container.

    Observera att värdena userId och containerId kommer från en UserIdSelection-komponent via handleSelectUser funktionen.

        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. Ersätt TODO 2 med följande kod. Som anges ovan avgör variabeln displayAudience om vi återger AudienceDisplay-komponenten eller UserIdSelection-komponenten . Funktioner för att uppdatera tillståndsvariablerna skickas också till komponenter som egenskaper.

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

Konfigurera AudienceDisplay-komponent

  1. Skapa och öppna en fil \src\AudienceDisplay.js i kodredigeraren. Lägg till följande import-uttryck:

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

    Observera att de objekt som importeras från Fluid Framework-biblioteket krävs för att definiera användare och containrar. I följande steg används AzureClient och InsecureTokenProvider för att konfigurera klienttjänsten (se TODO 1) medan SharedMap används för att konfigurera en containerSchema nödvändig för att skapa en container (se TODO 2).

  2. Lägg till följande funktionella komponenter och hjälpfunktioner:

        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
        }
    

    Observera att AudienceDisplay och AudienceList är funktionella komponenter som hanterar att hämta och återge målgruppsdata medan tryGetAudienceObject metoden hanterar skapandet av container- och målgruppstjänster.

Hämta container och målgrupp

Du kan använda en hjälpfunktion för att hämta fluiddata från objektet Målgrupp till visningslagret (react-tillståndet). Metoden tryGetAudienceObject anropas när vykomponenten läses in när ett användar-ID har valts. Det returnerade värdet tilldelas till en react-tillståndsegenskap.

  1. Ersätt TODO 1 med följande kod. Observera att värdena för userIduserNamecontainerId skickas in från appkomponenten. Om det inte finns någon containerIdskapas en ny container. Observera också att containerId lagras på URL-hashen. En användare som anger en session från en ny webbläsare kan kopiera URL:en från en befintlig sessionswebbläsare eller navigera till localhost:3000 och manuellt mata in container-ID:t. Med den här implementeringen vill vi omsluta anropet getContainer i en försöksfångst om användaren anger ett container-ID som inte finns. Mer information finns i dokumentationen för containrar .

        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;
    

Hämta målgruppen på komponentmonteringen

Nu när vi har definierat hur du hämtar Fluid-målgruppen måste vi be React att anropa tryGetAudienceObject när målgruppsvisningskomponenten är monterad.

  1. Ersätt TODO 2 med följande kod. Observera att användar-ID:t kommer från den överordnade komponenten som antingen user1user2 eller random. Om ID:t används randomMath.random() för att generera ett slumptal som ID. Dessutom mappas ett namn till användaren baserat på deras ID enligt beskrivningen i userNameList. Slutligen definierar vi de tillståndsvariabler som lagrar de anslutna medlemmarna och den aktuella användaren. fluidMembers lagrar en lista över alla medlemmar som är anslutna till containern medan currentMember innehåller medlemsobjektet som representerar den aktuella användaren som visar webbläsarkontexten.

        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. Ersätt TODO 3 med följande kod. Detta anropar tryGetAudienceObject när komponenten monteras och anger de returnerade målgruppsmedlemmarna till fluidMembers och currentMember. Observera att vi kontrollerar om ett målgruppsobjekt returneras om en användare anger ett containerId som inte finns och vi måste returnera dem till userIdSelection-vyn (props.onContainerNotFound() hanterar växling av vyn). Det är också bra att avregistrera händelsehanterare när React-komponenten demonteras genom att audience.offreturnera .

        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. Ersätt TODO 4 med följande kod. Observera att om fluidMembers eller currentMember inte har initierats återges en tom skärm. AudienceList-komponenten renderar medlemsdata med formatering (som ska implementeras i nästa avsnitt).

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

    Kommentar

    Anslut ionsövergångar kan resultera i korta tidsfönster där getMyself returnerar undefined. Det beror på att den aktuella klientanslutningen inte har lagts till i målgruppen ännu, så det går inte att hitta ett matchande anslutnings-ID. För att förhindra att React återger en sida utan målgruppsmedlemmar lägger vi till en lyssnare för att anropa updateMembersmembersChanged. Detta fungerar eftersom tjänstpubliken genererar en membersChanged händelse när containern är ansluten.

Skapa vyn

  1. Ersätt TODO 5 med följande kod. Observera att vi återger en listkomponent för varje medlem som skickas från AudienceDisplay-komponenten . För varje medlem jämför vi först med member.userIdcurrentMember.userId att kontrollera om medlemmen isSelf. På så sätt kan vi skilja klientanvändaren från andra användare och visa komponenten med en annan färg. Sedan push-överför vi listkomponenten till en list matris. Varje komponent visar medlemsdata som userIduserName och 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. Ersätt TODO 6 med följande kod. Detta renderar alla medlemselement som vi push-överförde till matrisen list .

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

Konfigurera UserIdSelection-komponent

  1. Skapa och öppna en fil \src\UserIdSelection.js i kodredigeraren. Den här komponenten innehåller användar-ID-knappar och indatafält för container-ID som gör det möjligt för slutanvändare att välja användar-ID och samarbetssession. Lägg till följande import instruktioner och funktionella komponenter:

    import { useState } from 'react';
    
    export const UserIdSelection = (props) => {
        // TODO 1: Define styles and handle user inputs
        return (
        // TODO 2: Return view components
        );
    }
    
  2. Ersätt TODO 1 med följande kod. Observera att onSelectUser funktionen uppdaterar tillståndsvariablerna i den överordnade appkomponenten och uppmanar till en vyändring. Metoden handleSubmit utlöses av knappelement som ska implementeras i TODO 2. handleChange Dessutom används metoden för att uppdatera tillståndsvariabelncontainerId. Den här metoden anropas från en händelselyssnare för indataelement som implementeras i TODO 2. Observera också att vi uppdaterar containerId att hämta värdet från ett HTML-element med ID:t containerIdInput (definierat i 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. Ersätt TODO 2 med följande kod. Detta renderar användar-ID-knapparna samt indatafältet för container-ID.

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

Starta fluidservern och kör programmet

Kommentar

För att matcha resten av den här instruktioner använder npx det här avsnittet och npm kommandon för att starta en Fluid-server. Koden i den här artikeln kan dock också köras mot en Azure Fluid Relay-server. Mer information finns i Så här etablerar du en Azure Fluid Relay-tjänst och gör så här: Anslut till en Azure Fluid Relay-tjänst

I kommandotolken kör du följande kommando för att starta fluidtjänsten.

npx @fluidframework/azure-local-service@latest

Öppna en ny kommandotolk och navigera till projektets rot. till exempel C:/My Fluid Projects/fluid-audience-tutorial. Starta programservern med följande kommando. Programmet öppnas i webbläsaren. Detta kan ta några minuter.

npm run start

Gå till localhost:3000 på en webbläsarflik för att visa det program som körs. Om du vill skapa en ny container väljer du en användar-ID-knapp medan du lämnar container-ID:t tomt. Om du vill simulera att en ny användare ansluter till containersessionen öppnar du en ny webbläsarflik och navigerar till localhost:3000. Den här gången anger du container-ID-värdet som kan hittas från den första webbläsarflikens URL som fortsätter http://localhost:3000/#.

Kommentar

Du kan behöva installera ytterligare ett beroende för att göra den här demonstrationen kompatibel med Webpack 5. Om du får ett kompileringsfel relaterat till ett "buffert" eller "url"-paket kör npm install -D buffer url du och försöker igen. Detta kommer att lösas i en framtida version av Fluid Framework.

Nästa steg

  • Prova att utöka demonstrationen med fler nyckel/värde-par i fältet additionalDetails i userConfig.
  • Överväg att integrera målgruppen i ett samarbetsprogram som använder distribuerade datastrukturer som SharedMap eller SharedString.
  • Läs mer om Målgrupp.

Dricks

När du gör ändringar i koden återskapas projektet automatiskt och programservern läses in igen. Men om du gör ändringar i containerschemat börjar de bara gälla om du stänger och startar om programservern. Det gör du genom att fokusera på kommandotolken och trycka på Ctrl-C två gånger. Kör npm run start sedan igen.