Delen via


Procedure: Doelgroepfuncties gebruiken in de Vloeiend Framework

In deze zelfstudie leert u hoe u de Vloeiend Framework Doelgroep gebruikt met React om een visuele demonstratie te maken van gebruikers die verbinding maken met een container. Het doelgroepobject bevat informatie met betrekking tot alle gebruikers die zijn verbonden met de container. In dit voorbeeld wordt de Azure-clientbibliotheek gebruikt om de container en doelgroep te maken.

In de volgende afbeelding ziet u de id-knoppen en een invoerveld voor de container-id. Als u het veld container-id leeg laat en op een knop gebruikers-id klikt, wordt er een nieuwe container gemaakt en wordt u toegevoegd als de geselecteerde gebruiker. De eindgebruiker kan ook een container-id invoeren en een gebruikers-id kiezen om lid te worden van een bestaande container als de geselecteerde gebruiker.

Een schermopname van een browser met knoppen voor het selecteren van een gebruiker.

In de volgende afbeelding ziet u meerdere gebruikers die zijn verbonden met een container die wordt vertegenwoordigd door vakken. Het vak dat in blauw wordt beschreven, vertegenwoordigt de gebruiker die de client bekijkt terwijl de vakken die zwart zijn gemarkeerd, de andere verbonden gebruikers vertegenwoordigen. Wanneer nieuwe gebruikers aan de container koppelen met unieke id's, neemt het aantal vakken toe.

Een schermopname van een browser met informatie voor vier verschillende containergebruikers.

Notitie

In deze zelfstudie wordt ervan uitgegaan dat u bekend bent met het Vloeiend Framework Overzicht en dat u de quickstart hebt voltooid. U moet ook bekend zijn met de basisprincipes van React, het maken van React-projecten en React Hooks.

Het project maken

  1. Open een opdrachtprompt en navigeer naar de bovenliggende map waar u het project wilt maken; bijvoorbeeld C:\My Fluid Projects.

  2. Voer de volgende opdracht uit bij de prompt. (Houd er rekening mee dat de CLI npx is, niet npm. Deze is geïnstalleerd toen u Node.js hebt geïnstalleerd.)

    npx create-react-app fluid-audience-tutorial
    
  3. Het project wordt gemaakt in een submap met de naam fluid-audience-tutorial. Navigeer ernaar met de opdracht cd fluid-audience-tutorial.

  4. In het project worden de volgende Fluid-bibliotheken gebruikt:

    Bibliotheek Beschrijving
    fluid-framework Bevat de gedistribueerde sharedMap-gegevensstructuur waarmee gegevens tussen clients worden gesynchroniseerd.
    @fluidframework/azure-client Definieert de verbinding met een Fluid-serviceserver en definieert het beginschema voor de Fluid-container.
    @fluidframework/test-client-utils Definieert de InsecureTokenProvider die nodig is om de verbinding met een Fluid Service te maken.

    Voer de volgende opdracht uit om de bibliotheken te installeren.

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

Het project codeeren

Statusvariabelen en onderdeelweergave instellen

  1. Open het bestand \src\App.js in de code-editor. Verwijder alle standaardinstructies import . Verwijder vervolgens alle markeringen uit de return instructie. Voeg vervolgens importinstructies toe voor onderdelen en React-hooks. Houd er rekening mee dat we de geïmporteerde onderdelen AudienceDisplay en UserIdSelection in de latere stappen gaan implementeren. Het bestand moet er als volgt uitzien:

        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. Vervang TODO 1 door de volgende code. Met deze code worden lokale statusvariabelen geïnitialiseerd die in de toepassing worden gebruikt. De displayAudience waarde bepaalt of we het component AudienceDisplay of het component UserIdSelection weergeven (zie TODO 2). De userId waarde is de gebruikers-id waarmee verbinding moet worden gemaakt met de container en de waarde is de containerId container die moet worden geladen. De handleSelectUser en handleContainerNotFound functies worden doorgegeven als callbacks naar de twee weergaven en statusovergangen beheren. handleSelectUser wordt aangeroepen bij het maken/laden van een container. handleContainerNotFound wordt aangeroepen bij het maken/laden van een container mislukt.

    Opmerking: de waarden userId en containerId zijn afkomstig van een UserIdSelection-onderdeel via de handleSelectUser functie.

        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. Vervang TODO 2 door de volgende code. Zoals hierboven vermeld, bepaalt de displayAudience variabele of we het component AudienceDisplay of het component UserIdSelection weergeven. Daarnaast worden functies voor het bijwerken van de statusvariabelen als eigenschappen doorgegeven aan onderdelen.

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

AudienceDisplay-onderdeel instellen

  1. Maak en open een bestand \src\AudienceDisplay.js in de code-editor. Voeg de volgende import instructies toe:

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

    Houd er rekening mee dat de objecten die zijn geïmporteerd uit de Vloeiend Framework-bibliotheek vereist zijn voor het definiëren van gebruikers en containers. In de volgende stappen worden AzureClient en InsecureTokenProvider gebruikt om de clientservice (zie TODO 1) te configureren terwijl de SharedMap wordt gebruikt om een containerSchema container te maken (zie TODO 2).

  2. Voeg de volgende functionele onderdelen en helperfuncties toe:

        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
        }
    

    De AudienceDisplay en AudienceList zijn functionele onderdelen die het ophalen en weergeven van doelgroepgegevens verwerken terwijl de tryGetAudienceObject methode het maken van container- en doelgroepservices afhandelt.

Container en doelgroep verkrijgen

U kunt een helperfunctie gebruiken om de fluid-gegevens, van het doelgroepobject, op te halen in de weergavelaag (de React-status). De tryGetAudienceObject methode wordt aangeroepen wanneer het weergaveonderdeel wordt geladen nadat een gebruikers-id is geselecteerd. De geretourneerde waarde wordt toegewezen aan een React-statuseigenschap.

  1. Vervang TODO 1 door de volgende code. Houd er rekening mee dat de waarden voor userId userName containerId deze waarden worden doorgegeven vanuit het app-onderdeel. Als er geen containerIdis, wordt er een nieuwe container gemaakt. Houd er ook rekening mee dat de hash van de containerId URL is opgeslagen. Een gebruiker die een sessie vanuit een nieuwe browser invoert, kan de URL vanuit een bestaande sessiebrowser kopiëren of naar de container-id navigeren localhost:3000 en handmatig invoeren. Met deze implementatie willen we de getContainer aanroep verpakken in een try catch in het geval dat de gebruiker een container-id invoert die niet bestaat. Ga naar de documentatie voor containers voor meer informatie.

        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;
    

De doelgroep op onderdeelkoppeling krijgen

Nu we hebben gedefinieerd hoe de Fluid-doelgroep kan worden opgehaald, moeten we React laten bellen tryGetAudienceObject wanneer het onderdeel Publieksweergave is gekoppeld.

  1. Vervang TODO 2 door de volgende code. Houd er rekening mee dat de gebruikers-id afkomstig is van het bovenliggende onderdeel als user1 user2 of random. Als de id is random gebruikt Math.random() voor het genereren van een willekeurig getal als de id. Daarnaast wordt een naam toegewezen aan de gebruiker op basis van hun id zoals opgegeven in userNameList. Ten slotte definiëren we de statusvariabelen waarmee de verbonden leden en de huidige gebruiker worden opgeslagen. fluidMembers slaat een lijst op van alle leden die zijn verbonden met de container, terwijl currentMember het lidobject dat de huidige gebruiker vertegenwoordigt die de browsercontext weergeeft.

        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. Vervang TODO 3 door de volgende code. Hiermee wordt het tryGetAudienceObject aangeroepen wanneer het onderdeel is gekoppeld en worden de geretourneerde doelgroepleden fluidMembers ingesteld op en currentMember. Opmerking: we controleren of een doelgroepobject wordt geretourneerd voor het geval een gebruiker een containerId invoert die niet bestaat en we moeten ze terugzetten naar de userIdSelection-weergave (props.onContainerNotFound() zal het schakelen van de weergave afhandelen). Het is ook een goede gewoonte om de registratie van gebeurtenis-handlers ongedaan te maken wanneer het React-onderdeel wordt ontkoppeld door terug te keren 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. Vervang TODO 4 door de volgende code. Als de fluidMembers of currentMember niet is geïnitialiseerd, wordt er een leeg scherm weergegeven. Het component AudienceList geeft de ledengegevens weer met stijl (te implementeren in de volgende sectie).

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

    Notitie

    Verbindingsovergangen kunnen resulteren in korte tijdsinstellingen waarin getMyself wordt geretourneerd undefined. Dit komt doordat de huidige clientverbinding nog niet is toegevoegd aan de doelgroep, zodat er geen overeenkomende verbindings-id kan worden gevonden. Om te voorkomen dat React een pagina weer te geven zonder doelgroepleden, voegen we een listener toe om aan te roepen updateMembers membersChanged. Dit werkt omdat de servicedoelgroep een membersChanged gebeurtenis verzendt wanneer de container is verbonden.

Maak de weergave

  1. Vervang TODO 5 door de volgende code. Houd er rekening mee dat we een lijstonderdeel weergeven voor elk lid dat is doorgegeven vanuit het component AudienceDisplay . Voor elk lid vergelijken member.userId we eerst om currentMember.userId te controleren of dat lid isSelf. Op deze manier kunnen we de clientgebruiker onderscheiden van de andere gebruikers en het onderdeel weergeven met een andere kleur. Vervolgens pushen we het lijstonderdeel naar een list matrix. Elk onderdeel geeft lidgegevens weer, zoals userId userName en 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. Vervang TODO 6 door de volgende code. Hiermee worden alle lidelementen weergegeven die we in de list matrix hebben gepusht.

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

UserIdSelection-onderdeel instellen

  1. Maak en open een bestand \src\UserIdSelection.js in de code-editor. Dit onderdeel bevat knoppen voor gebruikers-id's en invoervelden voor container-id's waarmee eindgebruikers hun gebruikers-id en gezamenlijke sessie kunnen kiezen. Voeg de volgende import instructies en functionele onderdelen toe:

    import { useState } from 'react';
    
    export const UserIdSelection = (props) => {
        // TODO 1: Define styles and handle user inputs
        return (
        // TODO 2: Return view components
        );
    }
    
  2. Vervang TODO 1 door de volgende code. Houd er rekening mee dat de onSelectUser functie de statusvariabelen in het bovenliggende app-onderdeel bijwerkt en een wijziging in de weergave vraagt. De handleSubmit methode wordt geactiveerd door knopelementen die worden geïmplementeerd in TODO 2. handleChange De methode wordt ook gebruikt om de containerId statusvariabele bij te werken. Deze methode wordt aangeroepen vanuit een gebeurtenislistener voor invoerelementen die is geïmplementeerd in TODO 2. Houd er ook rekening mee dat we de containerId waarde ophalen van een HTML-element met de id containerIdInput (gedefinieerd in 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. Vervang TODO 2 door de volgende code. Hiermee worden de knoppen voor de gebruikers-id en het invoerveld voor de container-id weergegeven.

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

Start de Fluid-server en voer de toepassing uit

Notitie

Deze sectie gebruikt npx en npm opdrachten om een fluid-server te starten om de rest van deze procedure te vinden. De code in dit artikel kan echter ook worden uitgevoerd op een Azure Fluid Relay-server. Zie Voor meer informatie : Een Azure Fluid Relay-service inrichten en het volgende doen: Verbinding maken met een Azure Fluid Relay-service

Voer in de opdrachtprompt de volgende opdracht uit om de Fluid-service te starten.

npx @fluidframework/azure-local-service@latest

Open een nieuwe opdrachtprompt en navigeer naar de hoofdmap van het project; bijvoorbeeld C:/My Fluid Projects/fluid-audience-tutorial. Start de toepassingsserver met de volgende opdracht. De toepassing wordt geopend in de browser. Dit kan enkele minuten in beslag nemen.

npm run start

Navigeer naar localhost:3000 een browsertabblad om de actieve toepassing weer te geven. Als u een nieuwe container wilt maken, selecteert u een knop gebruikers-id terwijl u de invoer van de container-id leeg laat. Als u een nieuwe gebruiker wilt simuleren die deelneemt aan de containersessie, opent u een nieuw browsertabblad en gaat u naar localhost:3000. Deze keer voert u de waarde van de container-id in die u kunt vinden via de URL http://localhost:3000/#van het eerste browsertabblad.

Notitie

Mogelijk moet u een extra afhankelijkheid installeren om deze demo compatibel te maken met Webpack 5. Als u een compilatiefout ontvangt met betrekking tot een buffer- of URL-pakket, voert u het uit npm install -D buffer url en probeert u het opnieuw. Dit wordt opgelost in een toekomstige release van Vloeiend Framework.

Volgende stappen

  • Probeer de demo uit te breiden met meer sleutel-waardeparen in het additionalDetails veld in userConfig.
  • Overweeg om doelgroep te integreren in een samenwerkingstoepassing die gebruikmaakt van gedistribueerde gegevensstructuren, zoals SharedMap of SharedString.
  • Meer informatie over doelgroep.

Tip

Wanneer u wijzigingen aanbrengt in de code, wordt het project automatisch opnieuw opgebouwd en wordt de toepassingsserver opnieuw geladen. Als u echter wijzigingen aanbrengt in het containerschema, worden deze alleen van kracht als u de toepassingsserver sluit en opnieuw start. Om dit te doen, geeft u de focus aan de opdrachtprompt en drukt u tweemaal op Ctrl-C. Voer vervolgens opnieuw uit npm run start .