次の方法で共有


Dice Roller コードのチュートリアル

Dice Roller サンプル アプリでは、ユーザーにサイコロが表示され、それをロールするボタンが表示されます。 サイコロがロールされると、Live Share SDK は Fluid Framework を使用してクライアント間でデータを同期するため、全員が同じ結果を確認できます。 データを同期するには、 app.js ファイルで次の手順を実行します。

  1. アプリケーションを設定する
  2. Fluid コンテナーを結合する
  3. 会議のステージビューを作成する
  4. 会議のステージビューをライブ共有に接続する
  5. サイド パネル ビューを記述する
  6. 設定ビューを記述する

DiceRoller サンプル

アプリケーションを設定します。

まず、必要なモジュールをインポートします。 このサンプルでは、 Live Share SDK の LiveState DDSLiveShareClient を 使用します。 このサンプルでは Teams 会議機能拡張がサポートされているため、 Microsoft Teams JavaScript クライアント ライブラリ (TeamsJS) を含める必要があります。 最後に、サンプルはローカルと Teams 会議の両方で実行するように設計されているため、 サンプルをローカルでテストするには、さらに Fluid Framework の部分を含める必要があります。

アプリケーションは、コンテナーで使用できる一連の 初期オブジェクト を定義するスキーマを使用して Fluid コンテナーを作成します。 このサンプルでは、LiveState を使用して、ロールされた現在のサイコロ値を格納します。

Teams 会議アプリには、コンテンツ、構成、ステージなど、複数のビューが必要です。 ビューを識別するのに役立つ start() 関数を作成できます。 この関数は、必要な初期化をレンダリングして実行するのに役立ちます。 このアプリでは、Web ブラウザーと Teams 会議内でのローカルでの実行の両方がサポートされています。 start()関数は、inTeams=true クエリ パラメーターを検索して、Teams で実行されているかどうかを判断します。

注:

Teams で実行する場合、アプリケーションは他の teams-js メソッドを呼び出す前に app.initialize() を呼び出す必要があります。

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 コンテナーに参加する必要があります。

会議のコンテナーへの参加は、Teams クライアント SDK からLiveShareHost インスタンスでLiveShareClientを初期化し、そのjoinContainer() メソッドを呼び出すのと同じくらい簡単です。

ローカルで実行する場合は、代わりに TestLiveShareHost インスタンスを使用してLiveShareClientを初期化できます。

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

ローカルでテストする場合、 TestLiveShareHost は、作成されたテスト コンテナーの ID を含むブラウザー URL を更新します。 そのリンクを他のブラウザー タブにコピーすると、 LiveShareClient が作成されたテスト コンテナーに参加します。 アプリケーション URL の変更がアプリケーションの操作に干渉する場合、テスト コンテナー ID の格納に使用する戦略は、LiveShareClientに渡される setLocalTestContainerId オプションと getLocalTestContainerId オプションを使用してカスタマイズできます。

Stageview を書き込む

多くの Teams 会議機能拡張アプリケーションは、表示フレームワークに React を使用するように設計されていますが、必須ではありません。 たとえば、このサンプルでは、標準の HTML/DOM メソッドを使用してビューをレンダリングします。

静的ビューから開始する

Fluid 機能を使用せずにローカル データを使用してビューを簡単に作成し、アプリの重要な部分を変更して Fluid を追加できます。

renderStage関数は、渡された HTML 要素にstageTemplateを追加し、[ロール] ボタンが選択されるたびにランダムなサイコロ値を持つ作業サイコロを作成します。 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);
}

会議のステージビューをライブ共有に接続する

LiveState の変更

アプリケーションで Live Share の使用を開始するには、ユーザーが rollButtonを選択したときに何が起こるかを最初に変更します。 ボタンは、ローカル状態を直接更新する代わりに、diceStatestate値として格納されている数値を更新します。 新しいstate.set()を呼び出すたびに、その値はすべてのクライアントに配布されます。 diceStateを変更すると、stateChanged イベントが生成され、イベント ハンドラーによってビューの更新がトリガーされる可能性があります。

このパターンは Fluid と Live Share の分散データ構造で一般的です。これは、ビューがローカルとリモートの両方の変更に対して同じように動作できるためです。

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

Fluid データに依存する

次に行う必要がある変更は、updateDice関数を変更して、updateDiceが呼び出されるたびにLiveStateから最新のサイコロ値を取得することです。

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

リモート変更を処理する

diceState から返される値は、特定の時点のスナップショットに過ぎません。 変更時にデータを最新の状態に保つためには、stateChanged イベントが送信されるたびにupdateDiceを呼び出すために、イベント ハンドラーを diceState に登録する必要があります。

diceState.on("stateChanged", updateDice);

LiveState を初期化する

アプリケーションで Live Share の変更の受信を開始する前に、最初に LiveState オブジェクトの initialize() を初期値で呼び出す必要があります。 この初期値は、他のユーザーによって送信された既存の状態を上書きしません。

LiveStateを初期化すると、先ほど登録したstateChanged イベントは、変更が行われるたびにトリガーを開始します。 ただし、初期値内で UI を更新するには、 updateDice()を呼び出します。

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

サイド パネル ビューを記述する

タブ contentUrl から sidePanel フレーム コンテキストで読み込まれたサイド パネルビューは、ユーザーが会議内でアプリを開いたときにサイド パネルに表示されます。 サイド パネル ビューの目的は、ユーザーが会議ステージにアプリを共有する前にアプリのコンテンツを選択できるようにすることです。 Live Share SDK アプリの場合は、サイド パネル ビューをアプリのコンパニオン エクスペリエンスとして使用することもできます。 サイド パネル ビューから joinContainer() を呼び出すと、Stageview が接続されているのと同じ Fluid コンテナーに接続されます。 その後、このコンテナーを使用して 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を設定するためにユーザー入力が必要ない場合でも必要です。

注:

ライブ共有の 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 トンネリング サービスを ダウンロードして使用します。

Teams がアプリに到達できるように、ngrok トンネルを作成する

  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 に移動します。 GitHub の Dice Roller サンプルから manifest.json を確認することもできます。

  2. manifest.json を開き、構成 URL を更新します。

    https://<<BASE_URI_DOMAIN>> を ngrok の http エンドポイントに置き換えます 。

  3. 次のシナリオでは、これらのプロパティを更新できます。

    • developer.name を自分の名前に設定します。
    • developer.websiteUrl を Web サイトで更新します。
    • developer.privacyUrl をプライバシー ポリシーを使用して更新します。
    • developer.termsOfUseUrl の使用条件を更新します。
  4. manifest.zip を作成するマニフェスト フォルダーの内容を zip 化します。 manifest.zipmanifest.json ソース ファイル、color アイコン、および outline アイコンのみが含まれていることを確認します。

    1. Windowsで、.\manifest ディレクトリ内のすべてのファイルを選択し、圧縮します。

    注:

    • 含まれているフォルダーを圧縮しないでください。
    • zip ファイルにわかりやすい名前を付けます。 たとえば、「 DiceRollerLiveShare 」のように入力します。

    マニフェストの詳細については、「Teams マニフェストのドキュメント」を参照してください

カスタム アプリを会議にアップロードする

  1. Teams を開きます。

  2. Teams の予定表から会議をスケジュールします。 少なくとも 1 人の出席者を会議に招待してください。

  3. 会議に参加します。

  4. 上部の会議ウィンドウで、[+ アプリ>アプリの管理] を選択します。

  5. [アプリの管理] ウィンドウで、カスタム アプリアップロードを選択します。

    1. カスタム アプリをアップロードするオプションが表示されない場合は、手順に従ってテナントでカスタム アプリを有効にします。
  6. ボタンを選択し、コンピューターから manifest.zip ファイルを選択します。

  7. [追加] を選択して、サンプル アプリを会議に追加します。

  8. [+ アプリ] を選択し、[アプリの検索] 検索ボックスに「Dice Roller」と入力します。

  9. 会議でアクティブ化するアプリを選択します。

  10. [保存] を選択します。

    Dice Roller アプリは、Teams 会議パネルに追加されます。

  11. サイド パネルで、ステージへの共有アイコンを選択します。 Teams 会議の会議ステージでユーザーとのライブ同期を開始します。

    ステージ アイコンに共有する

    これで、会議ステージにダイス ローラーが表示されます。

    会議ステージの画像

会議に招待されたユーザーは、会議に参加するときに、ステージ上でアプリを表示できます。

展開

コードをデプロイする準備ができたら、Teams Toolkit または [Teams 開発者ポータル] を使用して、アプリの zip ファイルをプロビジョニングしてアップロードできます。

注:

アプリをアップロードまたは配布する前に、プロビジョニングされた appId を manifest.json に追加する必要があります。

コード サンプル

サンプルの名前 説明 JavaScript
Dice Roller 接続されているすべてのクライアントがサイコロをふり、結果を表示できるようにします。 表示

次の手順

関連項目