Поделиться через


Руководство по коду Dice Roller

В примере приложения Dice Roller для пользователей отображаются кости с кнопкой для его наката. При накате костей пакет SDK для Live Share использует Fluid Framework для синхронизации данных между клиентами, поэтому каждый видит один и тот же результат. Чтобы синхронизировать данные, выполните следующие действия в файле app.js.

  1. Настройка приложения
  2. Присоединение к контейнеру Fluid
  3. Создание представления этапа собрания
  4. Подключение этапа собрания к Live Share
  5. Запись представления боковой панели
  6. Запись представления параметров

Пример DiceRoller

Настройка приложения

Вы можете начать с импорта необходимых модулей. В примере используются LiveState DDS и LiveShareClient из пакета SDK для Live Share. Этот пример поддерживает расширяемость собраний Teams, поэтому необходимо включить клиентскую библиотеку JavaScript (TeamsJS) Microsoft Teams. Наконец, пример предназначен для локального выполнения и в собрании Teams, поэтому для локального тестирования примера необходимо включить дополнительные компоненты Fluid Framework.

Приложения создают контейнеры Fluid с помощью схемы, определяющей набор начальных объектов , доступных контейнеру. В примере используется LiveState для хранения текущего значения костей, которое было свернуто.

Для приложений для собраний Teams требуется несколько представлений, таких как содержимое, конфигурация и этап. Вы можете создать start() функцию для идентификации представления. Эта функция помогает отрисовывать и выполнять любую необходимую инициализацию. Приложение поддерживает запуск как локально в веб-браузере, так и из собрания Teams. Функция start() ищет параметр запроса, inTeams=true чтобы определить, выполняется ли он в Teams.

Примечание.

При запуске в Teams приложение должно вызвать app.initialize() перед вызовом любых других методов teams-js.

В дополнение к параметру inTeams=true запроса можно использовать view=content|config|stage параметр запроса для определения представления, которое необходимо отобразить.

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

Присоединение к контейнеру Fluid

Не все представления приложения должны быть совместными. Представлению stageвсегда требуются функции совместной работы, представлению contentмогут потребоваться функции совместной работы, а представлению configникогда не нужны функции совместной работы. Для представлений, которым требуются функции совместной работы, необходимо присоединиться к контейнеру Fluid, связанному с текущим собранием.

Присоединить контейнер для собрания так же просто, как инициализировать LiveShareClient с экземпляром LiveShareHost из пакета SDK для клиента Teams, а затем вызвать его joinContainer() метод.

При локальном запуске можно инициализировать LiveShareClient с помощью экземпляра TestLiveShareHost .

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);
}

При локальном тестировании обновляет URL-адрес браузера, TestLiveShareHost чтобы он содержал идентификатор созданного тестового контейнера. Копирование этой ссылки на другие вкладки браузера приводит к присоединению LiveShareClient созданного тестового контейнера. Если изменение URL-адреса приложения мешает работе приложения, стратегию, используемую для хранения идентификатора тестовых контейнеров, можно настроить с помощью параметров setLocalTestContainerId и getLocalTestContainerId , передаваемых в LiveShareClient.

Написание представления Stageview

Многие приложения расширяемости собраний Teams предназначены для использования React для своей платформы представления, но это необязательно. Например, в этом примере используются стандартные методы HTML/DOM для отрисовки представления.

Начало со статического представления

Вы можете легко создать представление с использованием локальных данных без функций Fluid, а затем добавить функции Fluid, изменив некоторые ключевые части приложения.

Функция renderStage добавляет в переданный stageTemplate HTML-элемент и создает рабочий ролик кости со случайным значением кости при каждом нажатии кнопки Roll . diceState используется в следующих нескольких действиях.

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);
}

Подключение этапа собрания к Live Share

Изменение LiveState

Чтобы начать использовать Live Share в приложении, первое, что нужно изменить, это то, что происходит, когда пользователь выбирает rollButton. Вместо обновления локального состояния напрямую кнопка обновляет число, хранящееся state в качестве значения в diceState. При каждом вызове .set() с новым stateзначением это значение распространяется на все клиенты. Любые изменения в diceState могут привести stateChanged к возникновению события, а обработчик событий может активировать обновление представления.

Этот шаблон распространен в распределенных структурах данных Fluid и Live Share, так как он позволяет представлению вести себя одинаково при локальных и удаленных изменениях.

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

Использование данных Fluid

Следующее изменение, которое необходимо внести, — изменить функцию updateDice , чтобы получить последнее значение костей LiveState из каждого updateDice вызова.

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

Обработка удаленных изменений

Значения, возвращаемые из diceState, являются только моментальным снимком во времени. Чтобы данные обновлялись по мере их изменения, необходимо зарегистрировать diceState обработчик событий для вызова updateDice при каждой отправке stateChanged события.

diceState.on("stateChanged", updateDice);

Инициализация LiveState

Прежде чем начать получать изменения Live Share в приложении, необходимо сначала вызвать initialize()LiveState объект с начальным значением. Это начальное значение не перезаписывает существующее состояние, отправленное другими пользователями.

После инициализации LiveStatestateChanged зарегистрированное ранее событие начинает активироваться при каждом изменении. Однако для обновления пользовательского интерфейса в исходном значении вызовите .updateDice()

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

Запись представления боковой панели

Представление боковой панели, загруженное с помощью вкладки contentUrl с контекстом фрейма sidePanel, отображается пользователю на боковой панели, когда он открывает ваше приложение на собрании. Цель представления боковой панели — позволить пользователю выбрать содержимое приложения, прежде чем предоставлять доступ к приложению на этапе собрания. Для приложений пакета SDK Live Share представление боковой панели также можно использовать в качестве вспомогательного интерфейса приложения. Вызов joinContainer() из представления боковой панели подключается к тому же контейнеру Fluid, к которому подключено представление Stageview. Затем этот контейнер можно использовать для взаимодействия с Stageview. Убедитесь, что вы взаимодействуете с представлением Stageview и боковой панели всех пользователей.

В представлении боковой панели примера пользователю предлагается нажать кнопку демонстрации на сцене.

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));
}

Запись представления параметров

Представление параметров, загруженное configurationUrl в манифесте приложения, отображается пользователю при первом добавлении приложения в собрание Teams. Это представление позволяет разработчику настроить contentUrl для вкладки, закрепленной на собрании с учетом введенных пользователем данных. Эта страница является обязательной, даже если для задания значения не требуется вводить данные пользователем contentUrl.

Примечание.

Live Share' joinContainer() не поддерживается в контексте вкладки settings .

В представлении параметров примера пользователю предлагается нажать кнопку "Сохранить".

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);
}

Локальное тестирование

Вы можете протестировать свое приложение локально с помощью npm run start. Дополнительные сведения см. в кратком руководстве по началу работы.

Тестирование в Teams

После запуска приложения локально с помощью npm run startможно протестировать приложение в Teams. Если вы хотите протестировать приложение без развертывания, скачайте и используйте службу туннелирования ngrok.

Создание туннеля ngrok, чтобы разрешить Teams доступ к вашему приложению

  1. Скачайте ngrok.

  2. Используйте ngrok для создания туннеля с портом 8080. Выполните следующую команду:

     ngrok http 8080 --host-header=localhost
    

    Откроется новый терминал ngrok с новым URL-адресом, например https:...ngrok.io. Новый URL-адрес — это туннель, указывающий на ваше приложение, который необходимо обновить в manifest.json приложения.

Создание пакета приложения для отправки в Teams

  1. Перейдите в папку примера Dice Roller live-share-sdk\samples\javascript\01.dice-roller на своем компьютере. Вы также можете проверить manifest.json из примера Dice Roller на сайте GitHub.

  2. Откройте файл manifest.json и обновите URL-адрес конфигурации.

    Замените https://<<BASE_URI_DOMAIN>> своей конечной точкой HTTP из ngrok.

  3. Вы можете обновить следующие поля.

    • Настройте для developer.name ваше имя.
    • Обновите developer.websiteUrl с использованием вашего веб-сайта.
    • Обновите developer.privacyUrl с использованием вашей политики конфиденциальности.
    • Обновите developer.termsOfUseUrl с применением ваших условий использования.
  4. Заархивируйте содержимое папки манифеста для создания manifest.zip. Убедитесь, что manifest.zip содержит только исходный файл manifest.json, значок color и значок outline.

    1. В Windows выберите все файлы в каталоге .\manifest и сожмите их.

    Примечание.

    • Не запаковывайте содержащую папку.
    • Присвойте ZIP-файлу описательное имя. Например, DiceRollerLiveShare.

    Дополнительные сведения о манифесте см. в документации манифеста Teams

Отправка пользовательского приложения на собрание

  1. Откройте Teams.

  2. Запланируйте собрание в календаре Teams. Убедитесь, что вы приглашаете хотя бы одного участника собрания.

  3. Присоединитесь к собранию.

  4. В верхней части окна собрания выберите + Приложения>Управление приложениями.

  5. В области Управление приложениями выберите Отправить пользовательское приложение.

    1. Если вы не видите параметр Отправить пользовательское приложение, следуйте инструкциям, чтобы включить пользовательские приложения в клиенте.
  6. Выберите и отправьте файл manifest.zip со своего компьютера.

  7. Нажмите Добавить, чтобы добавить пример приложения в собрание.

  8. Выберите + Приложения, введите "Dice Roller" в поле поиска Найти приложение.

  9. Выберите приложение, чтобы активировать его на собрании.

  10. Нажмите кнопку Сохранить.

    Приложение Dice Roller добавляется на панель собрания Teams.

  11. На боковой панели щелкните значок демонстрации на сцене. Teams начинает динамическую синхронизацию с пользователями на сцене текущего собрания.

    Значок демонстрации на сцене

    Теперь на сцене собрания должно появиться приложение Dice-Roller.

    изображение сцены собрания

Пользователи, приглашенные на собрание, смогут увидеть ваше приложение на сцене после присоединения к собранию.

Развертывание

Когда вы будете готовы развернуть код, вы можете использовать набор средств Teams или портал разработчика Teams для подготовки и отправки ZIP-файла приложения.

Примечание.

Перед отправкой или распространением приложения необходимо добавить подготовленный идентификатор приложения в manifest.json.

Примеры кода

Название примера Описание JavaScript
Dice Roller Включение во всех подключенных клиентах возможности прокрутки игральной кости и просмотра результата. View

Следующий этап

См. также