Dice Roller Code-Lernprogramm

In der Dice Roller-Beispiel-App wird Benutzern ein Würfel mit einer Schaltfläche zum Würfeln angezeigt. Wenn der Würfel gewürfelt wird, verwendet das Live Share SDK das Fluid Framework, um die Daten clientübergreifend zu synchronisieren, sodass alle das gleiche Ergebnis sehen. Führen Sie zum Synchronisieren von Daten die folgenden Schritte in der Datei app.js aus:

  1. Einrichten der Anwendung
  2. Verknüpfen eines Fluid-Containers
  3. Schreiben der Besprechungs-Stageview
  4. Verbinden der Besprechungs-Stageview mit Live Share
  5. Schreiben der Seitenbereichsansicht
  6. Schreiben der Einstellungsansicht

DiceRoller-Beispiel

Einrichten der Anwendung

Sie können zunächst die erforderlichen Module importieren. Im Beispiel werden liveState DDS und LiveShareClient aus dem Live Share SDK verwendet. Das Beispiel unterstützt die Erweiterbarkeit von Teams-Besprechungen, sodass Sie die Microsoft Teams JavaScript-Clientbibliothek (TeamsJS) einschließen müssen. Schließlich ist das Beispiel so konzipiert, dass es sowohl lokal als auch in einer Teams-Besprechung ausgeführt wird, sodass Sie weitere Fluid Framework-Elemente einschließen müssen, um das Beispiel lokal zu testen.

Anwendungen erstellen Fluid-Container mithilfe eines Schemas, das eine Reihe von anfänglichen Objekten definiert, die für den Container verfügbar sind. Im Beispiel wird ein LiveState verwendet, um den aktuellen Würfelwert zu speichern, der gerollt wurde.

Teams-Besprechungs-Apps erfordern mehrere Ansichten, z. B. Inhalt, Konfiguration und Phase. Sie können eine start() Funktion erstellen, um die Ansicht zu identifizieren. Dies hilft beim Rendern und Ausführen aller erforderlichen Initialisierungen. Die App unterstützt die lokale Ausführung in einem Webbrowser und innerhalb einer Teams-Besprechung. Die start() Funktion sucht nach einem inTeams=true Abfrageparameter, um zu ermitteln, ob er in Teams ausgeführt wird.

Hinweis

Bei der Ausführung in Teams muss Ihre Anwendung aufrufen app.initialize() , bevor andere teams-js-Methoden aufgerufen werden.

Zusätzlich zum inTeams=true Abfrageparameter können Sie einen view=content|config|stage Abfrageparameter verwenden, um die Ansicht zu bestimmen, die gerendert werden muss.

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

const searchParams = new URL(window.location).searchParams;
const root = document.getElementById("content");

// Define container schema

const containerSchema = {
  initialObjects: { diceState: LiveState },
};

// STARTUP LOGIC

async function start() {
  // Check for page to display
  let view = searchParams.get("view") || "stage";

  // Check if we are running on stage.
  if (!!searchParams.get("inTeams")) {
    // Initialize teams app
    await app.initialize();
  }

  // Load the requested view
  switch (view) {
    case "content":
      renderSidePanel(root);
      break;
    case "config":
      renderSettings(root);
      break;
    case "stage":
    default:
      const { container } = await joinContainer();
      renderStage(container.initialObjects.diceState, root);
      break;
  }
}

start().catch((error) => console.error(error));

Verknüpfen eines Fluid-Containers

Nicht alle Ansichten Ihrer App müssen zusammenarbeiten. Die stage-Ansicht benötigt immer Funktionen für die Zusammenarbeit, die content-Ansicht benötigt möglicherweise Funktionen für die Zusammenarbeit, und die config-Ansicht sollte niemals Funktionen für die Zusammenarbeit benötigen. Für die Ansichten, die Funktionen für die Zusammenarbeit benötigen, müssen Sie einem Fluid-Container beitreten, der der aktuellen Besprechung zugeordnet ist.

Der Beitritt zum Container für die Besprechung ist so einfach wie das Initialisieren von LiveShareClient mit einem LiveShareHost instance aus dem Teams Client SDK und das anschließende Aufrufen der -joinContainer()Methode.

Wenn Sie lokal ausgeführt werden, können Sie stattdessen mit einem TestLiveShareHost instance initialisierenLiveShareClient.

async function joinContainer() {
  // Are we running in teams? If so, use LiveShareHost, otherwise use TestLiveShareHost
  const host = !!searchParams.get("inTeams")
    ? LiveShareHost.create()
    : TestLiveShareHost.create();
  // Create client
  const client = new LiveShareClient(host);
  // Join container
  return await client.joinContainer(containerSchema, onContainerFirstCreated);
}

Aktualisiert beim lokalen Testen die Browser-URL so, TestLiveShareHost dass sie die ID des erstellten Testcontainers enthält. Das Kopieren dieses Links auf andere Browserregisterkarten bewirkt, dass der LiveShareClient dem erstellten Testcontainer beigetreten ist. Wenn die Änderung der Anwendungs-URL den Betrieb der Anwendung beeinträchtigt, kann die zum Speichern der Testcontainer-ID verwendete Strategie mithilfe der an übergebenen LiveShareClientOptionen setLocalTestContainerId und getLocalTestContainerId angepasst werden.

Schreiben der Stageview

Viele Teams Meeting Extensibility-Anwendungen sind für die Verwendung von React für ihr Ansichtsframework konzipiert, dies ist jedoch nicht erforderlich. In diesem Beispiel werden beispielsweise HTML/DOM-Standardmethoden verwendet, um eine Ansicht zu rendern.

Beginnen mit einer statischen Ansicht

Es ist einfach, die Ansicht mit lokalen Daten ohne Fluid-Funktionalität zu erstellen und dann Fluid hinzuzufügen, indem Sie einige wichtige Teile der App ändern.

Die renderStage -Funktion fügt das stageTemplate an das übergebene HTML-Element an und erstellt jedes Mal, wenn die Roll-Schaltfläche ausgewählt wird, einen arbeitsfähigen Würfelroller mit einem zufälligen Würfelwert. diceState wird in den nächsten Schritten verwendet.

const stageTemplate = document.createElement("template");

stageTemplate["innerHTML"] = `
  <div class="wrapper">
    <div class="dice"></div>
    <button class="roll"> Roll </button>
  </div>
`;
function renderStage(diceState, elem) {
  elem.appendChild(stageTemplate.content.cloneNode(true));
  const rollButton = elem.querySelector(".roll");
  const dice = elem.querySelector(".dice");

  const updateDice = () => {
    // Get a random value between 1 and 6
    const diceValue = Math.floor(Math.random() * 6) + 1;
    // Unicode 0x2680-0x2685 are the sides of a die (⚀⚁⚂⚃⚄⚅).
    dice.textContent = String.fromCodePoint(0x267f + value);
  };
  rollButton.onclick = () => updateDice();
  updateDice(1);
}

Verbinden der Besprechungs-Stageview mit Live Share

Ändern von LiveState

Um Live Share in der Anwendung zu verwenden, müssen Sie zunächst ändern, was geschieht, wenn der Benutzer die rollButtonauswählt. Anstatt den lokalen Zustand direkt zu aktualisieren, aktualisiert die Schaltfläche die zahl, die als state Wert in diceStategespeichert ist. Wenn Sie mit einem neuen stateaufrufen.set(), wird dieser Wert an alle Clients verteilt. Änderungen am diceState können dazu führen, dass ein stateChanged Ereignis ausgegeben wird, und ein Ereignishandler kann eine Aktualisierung der Ansicht auslösen.

Dieses Muster ist in verteilten Datenstrukturen von Fluid und Live Share üblich, da es ermöglicht, dass sich die Ansicht sowohl bei lokalen als auch bei Remoteänderungen auf die gleiche Weise verhält.

rollButton.onclick = () =>
  diceState.set(Math.floor(Math.random() * 6) + 1);

Verwenden von Fluid-Daten

Die nächste Änderung, die vorgenommen werden muss, besteht darin, die updateDice Funktion so zu ändern, dass der letzte Würfelwert aus dem LiveState bei jedem Aufruf updateDice abgerufen wird.

const updateDice = () => {
  const diceValue = diceState.state;
  dice.textContent = String.fromCodePoint(0x267f + diceValue);
};

Behandeln von Remoteänderungen

Die von diceState zurückgegebenen Werte sind nur eine Momentaufnahme in der Zeit. Damit die Daten bei jeder Änderung auf dem neuesten Stand bleiben, muss ein Ereignishandler registriert diceState werden, um jedes Mal, wenn das stateChanged Ereignis gesendet wird, aufzurufenupdateDice.

diceState.on("stateChanged", updateDice);

Initialisieren von LiveState

Bevor Sie mit dem Empfangen der Live Share-Änderungen in der Anwendung beginnen können, müssen Sie zuerst für Ihr LiveState Objekt mit einem Anfangswert aufrufeninitialize(). Dieser Anfangswert überschreibt keinen vorhandenen Zustand, der von anderen Benutzern gesendet wurde.

Nachdem Sie initialisiert LiveStatehaben, wird das stateChanged zuvor registrierte Ereignis bei jeder Änderung ausgelöst. Rufen updateDice()Sie jedoch auf, um die Benutzeroberfläche innerhalb des Anfangswerts zu aktualisieren.

await diceState.initialize(1);
updateDice();

Schreiben der Seitenbereichsansicht

Die Seitenbereichsansicht, die über die Registerkarte "contentUrl" mit dem sidePanel-Framekontext geladen wird, wird dem Benutzer in einem Seitenbereich angezeigt, wenn er Ihre App innerhalb einer Besprechung öffnet. Das Ziel der Seitenbereichsansicht besteht darin, einem Benutzer die Auswahl von Inhalten für die App zu ermöglichen, bevor die App für die Besprechungsphase freigegeben wird. Für die Live Share SDK-Apps kann die Seitenbereichsansicht auch als Begleitoberfläche für die App verwendet werden. Der Aufruf joinContainer() von der Seitenbereichsansicht aus stellt eine Verbindung mit demselben Fluid-Container her, mit dem die Stageview verbunden ist. Dieser Container kann dann für die Kommunikation mit der Stageview verwendet werden. Stellen Sie sicher, dass Sie mit der Stageview- und Seitenbereichsansicht aller Benutzer kommunizieren.

In der Seitenbereichsansicht des Beispiels wird der Benutzer aufgefordert, die Schaltfläche "Freigeben in Phase" auszuwählen.

const sidePanelTemplate = document.createElement("template");

sidePanelTemplate["innerHTML"] = `
  <style>
    .wrapper { text-align: center }
    .title { font-size: large; font-weight: bolder; }
    .text { font-size: medium; }
  </style>
  <div class="wrapper">
    <p class="title">Lets get started</p>
    <p class="text">Press the share to stage button to share Dice Roller to the meeting stage.</p>
  </div>
`;

function renderSidePanel(elem) {
  elem.appendChild(sidePanelTemplate.content.cloneNode(true));
}

Schreiben der Einstellungsansicht

Die Einstellungsansicht, die configurationUrl in Ihrem App-Manifest geladen wird, wird einem Benutzer angezeigt, wenn er Ihre App zum ersten Mal zu einer Teams-Besprechung hinzufügen. In dieser Ansicht kann der Entwickler contentUrl für die Registerkarte konfigurieren, die basierend auf Benutzereingaben an die Besprechung angeheftet ist. Diese Seite ist derzeit auch dann erforderlich, wenn zum Festlegen des contentUrl keine Benutzereingabe erforderlich ist.

Hinweis

Live Share wird joinContainer() im Registerkartenkontext settings nicht unterstützt.

In der Einstellungsansicht des Beispiels wird der Benutzer aufgefordert, die Schaltfläche "Speichern" auszuwählen.

const settingsTemplate = document.createElement("template");

settingsTemplate["innerHTML"] = `
  <style>
    .wrapper { text-align: center }
    .title { font-size: large; font-weight: bolder; }
    .text { font-size: medium; }
  </style>
  <div class="wrapper">
    <p class="title">Welcome to Dice Roller!</p>
    <p class="text">Press the save button to continue.</p>
  </div>
`;

function renderSettings(elem) {
  elem.appendChild(settingsTemplate.content.cloneNode(true));

  // Save the configurable tab
  pages.config.registerOnSaveHandler((saveEvent) => {
    pages.config.setConfig({
      websiteUrl: window.location.origin,
      contentUrl: window.location.origin + "?inTeams=1&view=content",
      entityId: "DiceRollerFluidLiveShare",
      suggestedDisplayName: "DiceRollerFluidLiveShare",
    });
    saveEvent.notifySuccess();
  });

  // Enable the Save button in config dialog
  pages.config.setValidityState(true);
}

Lokal testen

Sie können Ihre App lokal mithilfe von npm run start testen. Weitere Informationen finden Sie im Schnellstarthandbuch.

In Teams testen

Nachdem Sie Ihre App lokal mit npm run start ausgeführt haben, können Sie Ihre App in Teams testen. Wenn Sie Ihre App ohne Bereitstellung testen möchten, laden Sie den ngrok Tunnelingdienst herunter, und verwenden Sie diesen.

Erstellen eines ngrok-Tunnels, damit Teams Ihre App erreichen kann

  1. Laden Sie ngrok herunter.

  2. Verwenden Sie ngrok, um einen Tunnel mit Port 8080 zu erstellen. Führen Sie den folgenden Befehl aus:

     ngrok http 8080 --host-header=localhost
    

    Ein neues ngrok-Terminal wird mit einer neuen URL geöffnet, z. B. https:...ngrok.io. Die neue URL ist der Tunnel, der auf Ihre App verweist, die in Ihrer manifest.json-App aktualisiert werden muss.

Erstellen des App-Pakets zum Hochladen in Teams

  1. Wechseln Sie zum Dice Roller Beispielordner live-share-sdk\samples\javascript\01.dice-roller auf Ihrem Computer. Sie können auch die manifest.json aus dem Dice Roller-Beispiel auf GitHub überprüfen.

  2. Öffnen Sie "manifest.json", und aktualisieren Sie die Konfigurations-URL.

    Ersetzen Sie https://<<BASE_URI_DOMAIN>> durch Ihren HTTP-Endpunkt aus ngrok.

  3. Sie können die folgenden Felder aktualisieren:

    • Legen Sie developer.name auf Ihren Namen fest.
    • Aktualisieren Sie developer.websiteUrl mit Ihrer Website.
    • Aktualisieren Sie developer.privacyUrl mit Ihrer Datenschutzrichtlinie.
    • Aktualisieren Sie developer.termsOfUseUrl mit Ihren Nutzungsbedingungen.
  4. Zippen Sie den Inhalt des Manifestordners, um manifest.zip zu erstellen. Stellen Sie sicher, dass manifest.zip nur die manifest.json-Quelldatei, das color-Symbol und das outline-Symbol enthält.

    1. Wählen Sie unter Windows alle Dateien im .\manifest-Verzeichnis aus, und komprimieren Sie sie.

    Hinweis

    • Zippen Sie den enthaltenden Ordner nicht.
    • Geben Sie Ihrer ZIP-Datei einen aussagekräftigen Namen. Beispiel: DiceRollerLiveShare.

    Weitere Informationen zum Manifest finden Sie in der Dokumentation zum Teams-Manifest.

Hochladen Ihrer benutzerdefinierten App in eine Besprechung

  1. Öffnen Sie Teams.

  2. Planen Sie eine Besprechung aus dem Kalender in Teams. Stellen Sie sicher, dass Sie mindestens einen Teilnehmer zur Besprechung einladen.

  3. Nehmen Sie an der Besprechung teil.

  4. Wählen Sie oben im Besprechungsfenster + Apps>Apps verwalten aus.

  5. Wählen Sie im Bereich Apps verwalten die Option Benutzerdefinierte App hochladen aus.

    1. Wenn die Option Benutzerdefinierte App hochladen nicht angezeigt wird, befolgen Sie die Anweisungen, um benutzerdefinierte Apps in Ihrem Mandanten zu aktivieren.
  6. Wählen Sie die manifest.zip-Datei aus, und laden Sie sie von Ihrem Computer hoch.

  7. Wählen Sie Hinzufügen aus, um Ihre Beispiel-App zur Besprechung hinzuzufügen.

  8. Wählen Sie +Apps aus, geben Sie Dice Roller in das Suchfeld App suchen ein.

  9. Wählen Sie die App aus, um sie in der Besprechung zu aktivieren.

  10. Wählen Sie Speichern.

    Die Dice Roller-App wird dem Teams-Besprechungsbereich hinzugefügt.

  11. Wählen Sie im Seitenbereich das Symbol "In Phase freigeben" aus. Teams startet eine Livesynchronisierung mit den Benutzern im Freigabefenster in der Besprechung.

    Symbol

    Jetzt sollte die Würfelrolle im Freigabefenster angezeigt werden.

    Abbildung des Freigabefensters

Benutzer, die zur Besprechung eingeladen sind, können Ihre App auf der Phase sehen, wenn sie an der Besprechung teilnehmen.

Bereitstellung

Nachdem Sie Ihren Code bereitgestellt haben, können Sie Teams Toolkit oder das Teams-Entwicklerportal verwenden, um die ZIP-Datei Ihrer App bereitzustellen und hochzuladen.

Hinweis

Sie müssen Ihre bereitgestellte appId dem manifest.json hinzufügen, bevor Sie die App hochladen oder verteilen.

Codebeispiele

Beispielname Beschreibung JavaScript
Dice Roller Ermöglichen Sie allen verbundenen Clients, einen Würfel zu rollen und das Ergebnis anzuzeigen. View

Nächster Schritt

Siehe auch