Partager via


Fonctionnalités principales de Live Share

Capture d’écran montrant un exemple d’utilisateurs jouant à un jeu de poker agile dans une réunion Teams, qui présente la fonctionnalité de partage en direct.

Le Kit de développement logiciel (SDK) Live Share peut être ajouté aux contextes sidePanel et meetingStage de l’extension de votre réunion avec un minimum d’efforts. Vous pouvez également utiliser le Kit de développement logiciel (SDK) dans des contextes de conversation et de canal content , tels que des onglets configurables, des onglets statiques et une vue d’étape collaborative.

Remarque

Les contextes live share content dans les conversations et les canaux sont pris en charge uniquement sur les clients web et de bureau Teams.

Cet article se concentre sur la façon d’intégrer le Kit de développement logiciel (SDK) Live Share dans votre application et les fonctionnalités clés du Kit de développement logiciel (SDK).

Conditions préalables

Installer le Kit de développement logiciel (SDK) JavaScript

Le Kit de développement logiciel (SDK) Live Share est un package JavaScript publié sur npm, que vous pouvez télécharger via npm ou yarn. Vous devez également installer les dépendances d’homologue Live Share, notamment fluid-framework et @fluidframework/azure-client. Si vous utilisez Live Share dans votre application d’onglet, vous devez également installer @microsoft/teams-js la version ou une version 2.23.0 ultérieure. Si vous souhaitez utiliser la classe pour le TestLiveShareHost développement de navigateur local, vous devez installer @fluidframework/test-client-utils les packages et start-server-and-test dans votre devDependencies.

NPM

npm install @microsoft/live-share fluid-framework @fluidframework/azure-client --save
npm install @microsoft/teams-js --save
npm install @fluidframework/test-client-utils start-server-and-test --save-dev

Yarn

yarn add @microsoft/live-share fluid-framework @fluidframework/azure-client
yarn add @microsoft/teams-js
yarn add @fluidframework/test-client-utils -dev

Inscrire des autorisations RSC

Pour activer le Kit de développement logiciel (SDK) Live Share pour votre extension d’onglet, vous devez d’abord ajouter les autorisations RSC suivantes dans le manifeste de votre application :

{
  // ...rest of your manifest here
  "configurableTabs": [
    {
        "configurationUrl": "<<YOUR_CONFIGURATION_URL>>",
        "canUpdateConfiguration": true,
        "scopes": [
            "groupchat",
            "team"
        ],
        "context": [
            // meeting contexts
            "meetingSidePanel",
            "meetingStage",
            // content contexts
            "privateChatTab",
            "channelTab",
            "meetingChatTab"
        ]
    }
  ],
  "validDomains": [
    "<<BASE_URI_ORIGIN>>"
  ],
  "authorization": {​
    "permissions": {​
      "resourceSpecific": [
        // ...other permissions here​
        {​
          "name": "LiveShareSession.ReadWrite.Chat",​
          "type": "Delegated"
        },
        {​
          "name": "LiveShareSession.ReadWrite.Group",​
          "type": "Delegated"
        },
        {​
          "name": "MeetingStage.Write.Chat",​
          "type": "Delegated"
        },
        {​
          "name": "ChannelMeetingStage.Write.Group",​
          "type": "Delegated"
        }
      ]​
    }​
  }​
}

Rejoindre une session

Suivez les étapes pour rejoindre une session associée à la réunion, à la conversation ou au canal d’un utilisateur :

  1. Initialisez LiveShareClient.
  2. Définir les structure de données que vous voulez synchroniser. Par exemple : LiveState ou SharedMap.
  3. Rejoindre le conteneur.

Exemple :

import { LiveShareClient, LiveState } from "@microsoft/live-share";
import { LiveShareHost } from "@microsoft/teams-js";
import { SharedMap } from "fluid-framework";

// Join the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: {
    liveState: LiveState,
    sharedMap: SharedMap,
  },
};
const { container } = await liveShare.joinContainer(schema);

// ... ready to start app sync logic

C’est tout ce qu’il faut pour configurer votre conteneur et rejoindre la session mappée à la réunion, à la conversation ou au canal. À présent, examinons les différents types de structures des données distribuées que vous pouvez utiliser avec le Kit de développement logiciel (SDK) Live Share.

Conseil

Vérifiez que le Kit de développement logiciel (SDK) du client Teams est initialisé avant d’appeler LiveShareHost.create().

Structures de données Live Share

Le Kit de développement logiciel (SDK) Live Share inclut un ensemble de nouvelles structures de données distribuées qui étendent la classe de DataObject Fluid, fournissant de nouveaux types d’objets avec état et sans état. Contrairement aux structures de données Fluid, les classes de LiveDataObject Live Share n’écrivent pas les modifications dans le conteneur Fluid, ce qui permet une synchronisation plus rapide. En outre, ces classes ont été conçues de bout en bout pour des scénarios courants dans les réunions, conversations et canaux Teams. Les scénarios courants incluent la synchronisation du contenu affiché par le présentateur, l’affichage des métadonnées pour chaque utilisateur de la session ou l’affichage d’un minuteur de compte à rebours.

Objet en direct Description
LivePresence Découvrez quels utilisateurs sont en ligne, définissez des propriétés personnalisées pour chaque utilisateur et diffusez les modifications apportées à leur participation.
LiveState Synchronisez toute valeur json sérialisable state .
LiveTimer Synchronisez un minuteur de compte à rebours pour un intervalle donné.
LiveEvent Diffusez des événements individuels avec des attributs de données personnalisés dans la charge utile.
LiveFollowMode Suivez des utilisateurs spécifiques, présentez-les à tous les participants de la session et commencez ou terminez les suspensions.

Exemple LivePresence

Capture d’écran montrant un exemple montrant les personnes disponibles dans une sessionTeams utilisant la présence live share.

La LivePresence classe facilite plus que jamais le suivi des personnes présentes dans la session. Lorsque vous appelez les .initialize() méthodes ou .updatePresence() , vous pouvez affecter des métadonnées personnalisées à cet utilisateur, telles que l’image de profil, l’identificateur du contenu qu’il affiche, etc. En écoutant presenceChanged les événements, chaque client reçoit le dernier LivePresenceUser objet, en réduisant toutes les mises à jour de présence dans un enregistrement unique pour chaque unique userId.

Voici quelques exemples qui LivePresence peuvent être utilisés dans votre application :

  • Obtention de Microsoft Teams userId, displayNameet roles de chaque utilisateur de la session.
  • Affichage d’informations personnalisées sur chaque utilisateur connecté à la session, telles qu’une URL d’image de profil.
  • Synchronisation des coordonnées dans une scène 3D où se trouve l’avatar de chaque utilisateur.
  • Signaler la position du curseur de chaque utilisateur dans un document texte.
  • Publication de la réponse de chaque utilisateur à une question de brise-glace pendant une activité de groupe.
import {
  LiveShareClient,
  LivePresence,
  PresenceState,
} from "@microsoft/live-share";
import { LiveShareHost } from "@microsoft/teams-js";

// Join the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: {
    presence: LivePresence,
  },
};
const { container } = await liveShare.joinContainer(schema);
const presence = container.initialObjects.presence;

// Register listener for changes to each user's presence.
// This should be done before calling `.initialize()`.
presence.on("presenceChanged", (user, local) => {
  console.log("A user presence changed:");
  console.log("- display name:", user.displayName);
  console.log("- state:", user.state);
  console.log("- custom data:", user.data);
  console.log("- change from local client", local);
  console.log("- change impacts local user", user.isLocalUser);
});

// Define the initial custom data for the local user (optional).
const customUserData = {
  picture: "DEFAULT_PROFILE_PICTURE_URL",
  readyToStart: false,
};
// Start receiving incoming presence updates from the session.
// This will also broadcast the user's `customUserData` to others in the session.
await presence.initialize(customUserData);

// Send a presence update, in this case once a user is ready to start an activity.
// If using role verification, this will throw an error if the user doesn't have the required role.
await presence.update({
  ...customUserData,
  readyToStart: true,
});

Les utilisateurs qui rejoignent une session à partir d’un seul appareil ont un enregistrement unique LivePresenceUser qui est partagé sur tous leurs appareils. Pour accéder à la dernière version data et state pour chacune de leurs connexions actives, vous pouvez utiliser l’API getConnections() à partir de la LivePresenceUser classe . Cette opération renvoie une liste d’objets LivePresenceConnection . Vous pouvez voir si une instance donnée LivePresenceConnection provient de l’appareil local à l’aide de la isLocalConnection propriété .

Chaque LivePresenceUser instance et LivePresenceConnection a une state propriété , qui peut être online, offlineou away. Un presenceChanged événement est émis lorsque l’état d’un utilisateur change. Par exemple, si un utilisateur se déconnecte de la session ou ferme l’application, son état devient offline.

Remarque

La mise à jour offline d’un LivePresenceUserstate objet vers peut prendre jusqu’à 20 secondes après la déconnexion d’un utilisateur de la session.

Exemple LiveState

Capture d’écran montrant un exemple d’état Live Share pour synchroniser la planète du système solaire qui est activement présentée à la réunion.

La LiveState classe permet de synchroniser l’état d’application simple pour les participants connectés. LiveState synchronise une valeur unique state , ce qui vous permet de synchroniser toute valeur sérialisable JSON, telle qu’une stringvaleur , numberou object.

Voici quelques exemples qui LiveState peuvent être utilisés dans votre application :

  • Définition de l’identificateur d’utilisateur du présentateur actuel pour créer une fonctionnalité de prise de contrôle .
  • Synchronisation du chemin d’itinéraire actuel de votre application pour vous assurer que tout le monde est sur la même page. Par exemple : /whiteboard/:whiteboardId.
  • Gestion de l’identificateur de contenu affiché par le présentateur actuel. Par exemple, sur taskId un tableau de tâches.
  • Synchronisation de l’étape actuelle dans une activité de groupe à plusieurs tours. Par exemple, la phase de devinette pendant le jeu Agile Poker.
  • Maintien d’une position de défilement synchronisée pour une fonctionnalité Suivez-moi .

Remarque

Contrairement à SharedMap, la state valeur dans LiveState est réinitialisée une fois que tous les utilisateurs se déconnectent d’une session.

Exemple :

import { LiveShareClient, LiveState } from "@microsoft/live-share";
import { LiveShareHost } from "@microsoft/teams-js";

// Join the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: { appState: LiveState },
};
const { container } = await liveShare.joinContainer(schema);
const { appState } = container.initialObjects;

// Register listener for changes to the state.
// This should be done before calling `.initialize()`.
appState.on("stateChanged", (planetName, local, clientId) => {
  // Update app with newly selected planet.
  // See which user made the change (optional)
  const clientInfo = await appState.getClientInfo(clientId);
});

// Set a default value and start listening for changes.
// This default value will not override existing for others in the session.
const defaultState = "Mercury";
await appState.initialize(defaultState);

// `.set()` will change the state for everyone in the session.
// If using role verification, this will throw an error if the user doesn't have the required role.
await appState.set("Earth");

Exemple LiveEvent

Capture d’écran montrant un exemple de client Teams affichant une notification en cas de modification dans l’événement.

LiveEvent est un excellent moyen d’envoyer des événements simples à d’autres clients connectés qui ne sont nécessaires qu’au moment de la livraison. Il est utile pour les scénarios tels que l’envoi de notifications de session ou l’implémentation de réactions personnalisées.

import { LiveEvent, LiveShareClient } from "@microsoft/live-share";
import { LiveShareHost } from "@microsoft/teams-js";

// Join the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: { customReactionEvent: LiveEvent },
};
const { container } = await liveShare.joinContainer(schema);
const { customReactionEvent } = container.initialObjects;

// Register listener to receive events sent through this object.
// This should be done before calling `.initialize()`.
customReactionEvent.on("received", async (kudosReaction, local, clientId) => {
  console.log("Received reaction:", kudosReaction, "from clientId", clientId);
  // See which user made the change (optional)
  const clientInfo = await customReactionEvent.getClientInfo(clientId);
  // Display notification in your UI
});

// Start listening for incoming events
await customReactionEvent.initialize();

// `.send()` will send your event value to everyone in the session.
// If using role verification, this will throw an error if the user doesn't have the required role.
const kudosReaction = {
  emoji: "❤️",
  forUserId: "SOME_OTHER_USER_ID",
};
await customReactionEvent.send(kudosReaction);

Exemple LiveTimer

Capture d’écran montrant un exemple de minuteur de comptage avec 9 secondes restantes.

LiveTimer fournit un compte à rebours simple qui est synchronisé pour tous les participants connectés. Il est utile pour les scénarios qui ont une limite de temps, comme un minuteur de méditation de groupe ou un minuteur d’arrondi pour un jeu. Vous pouvez également l’utiliser pour planifier des tâches pour tous les participants à la session, telles que l’affichage d’une invite de rappel.

import { LiveShareClient, LiveTimer } from "@microsoft/live-share";
import { LiveShareHost } from "@microsoft/teams-js";

// Join the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: { timer: LiveTimer },
};
const { container } = await liveShare.joinContainer(schema);
const { timer } = container.initialObjects;

// Register listeners for timer changes
// This should be done before calling `.initialize()`.

// Register listener for when the timer starts its countdown
timer.on("started", (config, local) => {
  // Update UI to show timer has started
});

// Register listener for when a paused timer has resumed
timer.on("played", (config, local) => {
  // Update UI to show timer has resumed
});

// Register listener for when a playing timer has paused
timer.on("paused", (config, local) => {
  // Update UI to show timer has paused
});

// Register listener for when a playing timer has finished
timer.on("finished", (config) => {
  // Update UI to show timer is finished
});

// Register listener for the timer progressed by 20 milliseconds
timer.on("onTick", (milliRemaining) => {
  // Update UI to show remaining time
});

// Start synchronizing timer events for users in session
await timer.initialize();

// Start a 60 second timer for users in the session.
// If using role verification, this will throw an error if the user doesn't have the required role.
const durationInMilliseconds = 1000 * 60;
await timer.start(durationInMilliseconds);

// Pause the timer for users in session
// If using role verification, this will throw an error if the user doesn't have the required role.
await timer.pause();

// Resume the timer for users in session
// If using role verification, this will throw an error if the user doesn't have the required role.
await timer.play();

Exemple LiveFollowMode

L’image montre trois clients avec trois vues distinctes : un présentateur, un utilisateur qui suit le présentateur et un utilisateur avec sa propre vue privée avec la possibilité de revenir au présentateur.

La LiveFollowMode classe combine et LiveState en une seule classe, ce qui vous permet d’implémenter facilement les LivePresence modes d’utilisateur et de présentateur dans votre application. Cela vous permet d’implémenter des modèles familiers à partir d’applications collaboratives populaires telles que PowerPoint Live, Excel Live et Tableau blanc. Contrairement au partage d’écran, LiveFollowMode vous permet d’afficher du contenu avec une qualité élevée, une meilleure accessibilité et des performances améliorées. Les utilisateurs peuvent facilement basculer entre leurs vues privées et suivre d’autres utilisateurs.

Vous pouvez utiliser la startPresenting() fonction pour prendre le contrôle de l’application pour tous les autres utilisateurs de la session. Vous pouvez également autoriser les utilisateurs à sélectionner individuellement des utilisateurs spécifiques qu’ils souhaitent suivre à l’aide de la followUser() fonction . Dans les deux scénarios, les utilisateurs peuvent entrer temporairement une vue privée avec la beginSuspension() fonction ou se synchroniser à nouveau avec le présentateur avec la endSuspension() fonction. Pendant ce temps, la update() fonction permet à l’utilisateur local d’informer d’autres clients dans la session de leur propre personnel stateValue. Comme pour LivePresence, vous pouvez écouter les modifications apportées à chaque utilisateur via un écouteur d’événements stateValuepresenceChanged .

LiveFollowMode expose également un state objet, qui se met à jour dynamiquement en fonction de l’utilisateur que l’utilisateur local suit. Par exemple, si l’utilisateur local ne suit personne, la state.value propriété correspond à la dernière stateValue diffusion de l’utilisateur local via update(). Toutefois, si l’utilisateur local suit un présentateur, la state.value propriété correspond au plus récent stateValuede l’utilisateur de présentation. Comme pour LiveState, vous pouvez écouter les modifications apportées à la valeur à l’aide state d’un écouteur d’événements stateChanged . Pour plus d’informations sur l’objet, consultez Informations de référence sur l’interface stateIFollowModeState.

Voici quelques exemples que vous pouvez utiliser LiveFollowMode dans votre application :

  • Synchroniser les positions de la caméra dans une scène 3D avec cobrowse pendant une révision de conception.
  • Mettez à jour pour slideId ouvrir dans un carrousel pour des présentations et des discussions productives.
  • Diffusez le path à ouvrir dans le routeur de votre application.

Exemple :

import {
  LiveShareClient,
  LiveFollowMode,
  FollowModeType,
} from "@microsoft/live-share";
import { LiveShareHost } from "@microsoft/teams-js";

// Join the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: {
    followMode: LiveFollowMode,
  },
};
const { container } = await liveShare.joinContainer(schema);
const followMode = container.initialObjects.followMode;

// As an example, we will assume there is a button in the application document
const button = document.getElementById("action-button");
// As an example, we will assume there is a div with text showing the follow state
const infoText = document.getElementById("info-text");

// Register listener for changes to the `state` value to use in your app.
// This should be done before calling `.initialize()`.
followMode.on("stateChanged", (state, local, clientId) => {
  console.log("The state changed:");
  console.log("- state value:", state.value);
  console.log("- follow mode type:", state.type);
  console.log("- following user id:", state.followingUserId);
  console.log(
    "- count of other users also following user",
    state.otherUsersCount
  );
  console.log(
    "- state.value references local user's stateValue",
    state.isLocalValue
  );
  // Can optionally get the relevant user's presence object
  const followingUser = followMode.getUserForClient(clientId);
  switch (state.type) {
    case FollowModeType.local: {
      // Update app to reflect that the user isn't following anyone and there is no presenter.
      infoText.innerHTML = "";
      // Show a "Start presenting" button in your app.
      button.innerHTML = "Start presenting";
      button.onclick = followMode.startPresenting;
      // Note: state.isLocalValue will be true.
      break;
    }
    case FollowModeType.activeFollowers: {
      // Update app to reflect that the local user is being followed by other users.
      infoText.innerHTML = `${state.otherUsersCount} users are following you`;
      // Does not mean that the local user is presenting to everyone, so you can still show the "Start presenting" button.
      button.innerHTML = "Present to all";
      button.onclick = followMode.startPresenting;
      // Note: state.isLocalValue will be true.
      break;
    }
    case FollowModeType.activePresenter: {
      // Update app to reflect that the local user is actively presenting to everyone.
      infoText.innerHTML = `You are actively presenting to everyone`;
      // Show a "Stop presenting" button in your app.
      button.innerHTML = "Stop presenting";
      button.onclick = followMode.stopPresenting;
      // Note: state.isLocalValue will be true.
      break;
    }
    case FollowModeType.followPresenter: {
      // The local user is following a remote presenter.
      infoText.innerHTML = `${followingUser?.displayName} is presenting to everyone`;
      // Show a "Take control" button in your app.
      button.innerHTML = "Take control";
      button.onclick = followMode.startPresenting;
      // Note: state.isLocalValue will be false.
      break;
    }
    case FollowModeType.suspendFollowPresenter: {
      // The local user is following a remote presenter but has an active suspension.
      infoText.innerHTML = `${followingUser?.displayName} is presenting to everyone`;
      // Show a "Sync to presenter" button in your app.
      button.innerHTML = "Sync to presenter";
      button.onclick = followMode.endSuspension;
      // Note: state.isLocalValue will be true.
      break;
    }
    case FollowModeType.followUser: {
      // The local user is following a specific remote user.
      infoText.innerHTML = `You are following ${followingUser?.displayName}`;
      // Show a "Stop following" button in your app.
      button.innerHTML = "Stop following";
      button.onclick = followMode.stopFollowing;
      // Note: state.isLocalValue will be false.
      break;
    }
    case FollowModeType.suspendFollowUser: {
      // The local user is following a specific remote user but has an active suspension.
      infoText.innerHTML = `You were following ${followingUser?.displayName}`;
      // Show a "Resume following" button in your app.
      button.innerHTML = "Resume following";
      button.onclick = followMode.endSuspension;
      // Note: state.isLocalValue will be true.
      break;
    }
    default: {
      break;
    }
  }
  const newCameraPosition = state.value;
  // TODO: apply new camera position
});

// Register listener for changes to each user's personal state updates.
// This should be done before calling `.initialize()`.
followMode.on("presenceChanged", (user, local) => {
  console.log("A user presence changed:");
  console.log("- display name:", user.displayName);
  console.log("- state value:", user.data?.stateValue);
  console.log("- user id user is following:", user.data?.followingUserId);
  console.log("- change from local client", local);
  console.log("- change impacts local user", user.isLocalUser);
  // As an example, we will assume there is a button for each user in the session.
  document.getElementById(`follow-user-${user.userId}-button`).onclick = () => {
    followMode.followUser(user.userId);
  };
  // Update 3D scene to reflect this user's camera position (e.g., orb + display name)
  const userCameraPosition = user.data?.stateValue;
});

// Define the initial stateValue for the local user (optional).
const startingCameraPosition = {
  x: 0,
  y: 0,
  z: 0,
};
// Start receiving incoming presence updates from the session.
// This will also broadcast the user's `startingCameraPosition` to others in the session.
await followMode.initialize(startingCameraPosition);

// Example of an event listener for a camera position changed event.
// For something like a camera change event, you should use a debounce function to prevent sending updates too frequently.
// Note: it helps to distinguish changes initiated by the local user (e.g., drag mouse) separately from other change events.
function onCameraPositionChanged(position, isUserAction) {
  // Broadcast change to other users so that they have their latest camera position
  followMode.update(position);
  // If the local user changed the position while following another user, we want to suspend.
  // Note: helps to distinguish changes initiated by the local user (e.g., drag mouse) separately from other change events.
  if (!isUserAction) return;
  switch (state.type) {
    case FollowModeType.followPresenter:
    case FollowModeType.followUser: {
      // This will trigger a "stateChanged" event update for the local user only.
      followMode.beginSuspension();
      break;
    }
    default: {
      // No need to suspend for other types
      break;
    }
  }
}

Dans meetingStage les contextes, vos utilisateurs collaborent et présentent de manière synchrone pour faciliter des discussions plus productives. Lorsqu’un utilisateur présente du contenu à la phase de réunion, vous devez appeler l’API startPresenting() pour le présentateur initial. Dans content des contextes tels que la vue d’étape collaborative, le contenu est le plus souvent consommé de manière asynchrone. Dans ce cas, il est préférable de laisser les utilisateurs opter pour la collaboration en temps réel, par exemple via un bouton « Suivre ». À l’aide de l’API teamsJs.app.getContext() dans le Kit de développement logiciel (SDK) JavaScript Teams, vous pouvez facilement ajuster vos fonctionnalités en conséquence.

Exemple :

import {
  LiveShareClient,
  LiveFollowMode,
  FollowModeType,
} from "@microsoft/live-share";
import {
  app,
  meeting,
  FrameContexts,
  LiveShareHost,
} from "@microsoft/teams-js";

// Join the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: {
    followMode: LiveFollowMode,
  },
};
const { container } = await liveShare.joinContainer(schema);
const followMode = container.initialObjects.followMode;

// Get teamsJs context
const context = await app.getContext();
// Take control if in meetingStage context and local user is initial presenter
if (context.page?.frameContext === FrameContexts.meetingStage) {
  // Take control if in meetingStage context and local user is initial presenter
  meeting.getAppContentStageSharingState((error, state) => {
    const isShareInitiator = state?.isShareInitiator;
    if (!isShareInitiator) return;
    // The user is the initial presenter, so we "take control"
    await followMode.startPresenting();
  });
}
// TODO: rest of app logic

Vérification des rôles pour les structures de données actives

Les réunions dans Teams incluent des appels, des réunions toutes mains et des salles de classe en ligne. Les participants à la réunion peuvent s’étendre à plusieurs organisations, avoir des privilèges différents ou avoir des objectifs différents. Par conséquent, il est important de respecter les privilèges des différents rôles d’utilisateur pendant les réunions. Les objets en direct sont conçus pour prendre en charge la vérification des rôles, ce qui vous permet de définir les rôles autorisés à envoyer des messages pour chaque objet actif individuel. Par exemple, vous avez sélectionné l’option qui autorise uniquement les présentateurs de réunion et les organisateurs à contrôler la lecture vidéo. Toutefois, les invités et les participants peuvent toujours demander les prochaines vidéos à regarder.

Remarque

Lors de l’accès à Live Share à partir d’une conversation ou d’un content contexte de canal, tous les utilisateurs auront les Organizer rôles et Presenter .

Dans l’exemple suivant, où seuls les présentateurs et les organisateurs peuvent prendre le contrôle, LiveState est utilisé pour synchroniser quel utilisateur est le présentateur actif :

import {
  LiveShareClient,
  LiveState,
  UserMeetingRole,
} from "@microsoft/live-share";
import { LiveShareHost } from "@microsoft/teams-js";

// Join the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: { appState: LiveState },
};
const { container } = await liveShare.joinContainer(schema);
const { appState } = container.initialObjects;

// Register listener for changes to state
appState.on("stateChanged", (state, local) => {
  // Update local app state
});

// Set roles who can change state and start listening for changes
const initialState = {
  documentId: "INITIAL_DOCUMENT_ID",
};
const allowedRoles = [UserMeetingRole.organizer, UserMeetingRole.presenter];
await appState.initialize(initialState, allowedRoles);

async function onSelectEditMode(documentId) {
  try {
    await appState.set({
      documentId,
    });
  } catch (error) {
    console.error(error);
  }
}

async function onSelectPresentMode(documentId) {
  try {
    await appState.set({
      documentId,
      presentingUserId: "LOCAL_USER_ID",
    });
  } catch (error) {
    console.error(error);
  }
}

Écoutez vos clients pour comprendre leurs scénarios avant d’implémenter la vérification de rôle dans votre application, en particulier pour le rôle d’Organisateur. Il n’existe aucune garantie qu’un organisateur de réunion sera présent dans la réunion. En règle générale, tous les utilisateurs sont organisateurs ou présentateurs lors de la collaboration au sein d’une organisation. Si un utilisateur est un Participant, il s’agit généralement d’une décision intentionnelle au nom d’un organisateur de la réunion.

Dans certains cas, un utilisateur peut avoir plusieurs rôles. Par exemple, un organisateur est également un présentateur. En outre, les participants à la réunion qui sont externes au locataire hébergeant la réunion ont le rôle Invité , mais peuvent également avoir des privilèges de présentateur . Cela offre plus de flexibilité dans la façon dont vous utilisez la vérification des rôles dans votre application.

Remarque

Le Kit de développement logiciel (SDK) Live Share n’est pas pris en charge pour les utilisateurs invités dans les réunions de canal.

Structures de données distribuées Fluid

Le Kit de développement logiciel (SDK) Live Share prend en charge toute structure de données distribuées incluse dans Infrastructure Fluid. Ces fonctionnalités servent d’ensemble de primitives que vous pouvez utiliser pour créer des scénarios de collaboration robustes, tels que des mises à jour en temps réel d’une liste de tâches ou la co-création de texte dans un code HTML <textarea>.

LiveDataObject Contrairement aux classes mentionnées dans cet article, les structures de données Fluid ne se réinitialisent pas après la fermeture de votre application. Cela est idéal pour les scénarios tels que la réunion sidePanel et content les contextes, où les utilisateurs ferment et rouvrent fréquemment votre application.

Fluid Framework prend officiellement en charge les types de structures de données distribuées suivants :

Objet partagé Description
SharedMap Un magasin de valeurs clés distribué. Définissez un objet JSON sérialisable pour une clé donnée afin de synchroniser cet objet pour tous les membres de la session.
SharedSegmentSequence Structure de données de type liste permettant de stocker un groupe d’éléments (appelés segments) dans des positions définies.
SharedString Séquence de chaîne distribuée optimisée pour la modification du texte des documents ou des zones de texte.

Voyons comment SharedMap fonctionne. Dans cet exemple, nous avons utilisé SharedMap pour créer une fonctionnalité de sélection.

import { LiveShareClient } from "@microsoft/live-share";
import { LiveShareHost } from "@microsoft/teams-js";
import { SharedMap } from "fluid-framework";

// Join the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: { playlistMap: SharedMap },
};
const { container } = await liveShare.joinContainer(schema);
const playlistMap = container.initialObjects.playlistMap;

// Register listener for changes to values in the map
playlistMap.on("valueChanged", (changed, local) => {
  const video = playlistMap.get(changed.key);
  // Update UI with added video
});

function onClickAddToPlaylist(video) {
  // Add video to map
  playlistMap.set(video.id, video);
}

Remarque

Les objets principaux DDS Infrastructure Fluid ne prennent pas en charge la vérification du rôle de la réunion. Tous les participants à la réunion peuvent modifier les données stockées via ces objets.

Test du navigateur local

Vous pouvez tester localement le Kit de développement logiciel (SDK) Live Share dans votre navigateur à l’aide de la TestLiveShareHost classe sans installer votre application dans Teams. Cela est utile pour tester les principales fonctionnalités collaboratives de votre application dans un environnement familier localhost .

Exemple :

import {
  LiveShareClient,
  TestLiveShareHost,
  LiveState,
} from "@microsoft/live-share";
import { LiveShareHost } from "@microsoft/teams-js";
import { SharedMap } from "fluid-framework";

/**
 * Detect whether you are in Teams or local environment using your preferred method.
 * Options for this include: environment variables, URL params, Teams FX, etc.
 */
const inTeams = process.env.IN_TEAMS;
// Join the Fluid container
const host = inTeams ? LiveShareHost.create() : TestLiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: {
    liveState: LiveState,
    sharedMap: SharedMap,
  },
};
const { container } = await liveShare.joinContainer(schema);

// ... ready to start app sync logic

La TestLiveShareHost classe utilise le tinylicious serveur de test de Fluid Framework, plutôt que notre service Relais Azure Fluid de production. Pour ce faire, vous devez ajouter quelques scripts à votre package.json pour démarrer le serveur de test. Vous devez également ajouter les @fluidframework/test-client-utils packages et start-server-and-test au devDependencies dans votre package.json.

{
  "scripts": {
    "start": "start-server-and-test start:server 7070 start:client",
    "start:client": "{YOUR START CLIENT COMMAND HERE}",
    "start:server": "npx tinylicious@latest"
  },
  "devDependencies": {
    "@fluidframework/test-client-utils": "^1.3.6",
    "start-server-and-test": "^2.0.0"
  }
}

Lorsque vous démarrez votre application de cette façon, le LiveShareClient ajoute #{containerId} à votre URL, si elle n’existe pas. Vous pouvez ensuite copier et coller l’URL dans une nouvelle fenêtre de navigateur pour vous connecter au même conteneur Fluid.

Remarque

Par défaut, tous les clients connectés via TestLiveShareHost auront presenter des rôles et organizer .

Exemples de code

Exemple de nom Description JavaScript TypeScript
Lanceur de dés Permettre à tous les clients connectés de lancer un dé et de visualiser le résultat. View View
Agile Poker Permettre à tous les clients connectés de jouer à Agile Poker. View N/A
Modèle 3D Permettre à tous les clients connectés d’afficher un modèle 3D ensemble. N/A View
Minuteur Permettre à tous les clients connectés d’afficher un minuteur de compte à rebours. N/A View
Avatars de présence Afficher les avatars de présence pour tous les clients connectés. N/A View

Étape suivante

Voir aussi