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.
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.
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
Open een opdrachtprompt en navigeer naar de bovenliggende map waar u het project wilt maken; bijvoorbeeld
C:\My Fluid Projects
.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
Het project wordt gemaakt in een submap met de naam
fluid-audience-tutorial
. Navigeer ernaar met de opdrachtcd fluid-audience-tutorial
.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
Open het bestand
\src\App.js
in de code-editor. Verwijder alle standaardinstructiesimport
. Verwijder vervolgens alle markeringen uit dereturn
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 ); }
Vervang
TODO 1
door de volgende code. Met deze code worden lokale statusvariabelen geïnitialiseerd die in de toepassing worden gebruikt. DedisplayAudience
waarde bepaalt of we het component AudienceDisplay of het component UserIdSelection weergeven (zieTODO 2
). DeuserId
waarde is de gebruikers-id waarmee verbinding moet worden gemaakt met de container en de waarde is decontainerId
container die moet worden geladen. DehandleSelectUser
enhandleContainerNotFound
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]);
Vervang
TODO 2
door de volgende code. Zoals hierboven vermeld, bepaalt dedisplayAudience
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
Maak en open een bestand
\src\AudienceDisplay.js
in de code-editor. Voeg de volgendeimport
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 eencontainerSchema
container te maken (zieTODO 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.
Vervang
TODO 1
door de volgende code. Houd er rekening mee dat de waarden vooruserId
userName
containerId
deze waarden worden doorgegeven vanuit het app-onderdeel. Als er geencontainerId
is, wordt er een nieuwe container gemaakt. Houd er ook rekening mee dat de hash van decontainerId
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 navigerenlocalhost:3000
en handmatig invoeren. Met deze implementatie willen we degetContainer
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.
Vervang
TODO 2
door de volgende code. Houd er rekening mee dat de gebruikers-id afkomstig is van het bovenliggende onderdeel alsuser1
user2
ofrandom
. Als de id israndom
gebruiktMath.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 inuserNameList
. 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, terwijlcurrentMember
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();
Vervang
TODO 3
door de volgende code. Hiermee wordt hettryGetAudienceObject
aangeroepen wanneer het onderdeel is gekoppeld en worden de geretourneerde doelgroepledenfluidMembers
ingesteld op encurrentMember
. 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 kerenaudience.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) }; }); }, []);
Vervang
TODO 4
door de volgende code. Als defluidMembers
ofcurrentMember
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 geretourneerdundefined
. 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 roepenupdateMembers
membersChanged
. Dit werkt omdat de servicedoelgroep eenmembersChanged
gebeurtenis verzendt wanneer de container is verbonden.
Maak de weergave
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 vergelijkenmember.userId
we eerst omcurrentMember.userId
te controleren of dat lidisSelf
. 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 eenlist
matrix. Elk onderdeel geeft lidgegevens weer, zoalsuserId
userName
enadditionalDetails
.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> ); });
Vervang
TODO 6
door de volgende code. Hiermee worden alle lidelementen weergegeven die we in delist
matrix hebben gepusht.return ( <div> {list} </div> );
UserIdSelection-onderdeel instellen
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 volgendeimport
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 ); }
Vervang
TODO 1
door de volgende code. Houd er rekening mee dat deonSelectUser
functie de statusvariabelen in het bovenliggende app-onderdeel bijwerkt en een wijziging in de weergave vraagt. DehandleSubmit
methode wordt geactiveerd door knopelementen die worden geïmplementeerd inTODO 2
.handleChange
De methode wordt ook gebruikt om decontainerId
statusvariabele bij te werken. Deze methode wordt aangeroepen vanuit een gebeurtenislistener voor invoerelementen die is geïmplementeerd inTODO 2
. Houd er ook rekening mee dat we decontainerId
waarde ophalen van een HTML-element met de idcontainerIdInput
(gedefinieerd inTODO 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); };
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 inuserConfig
. - 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
.