Dice Roller コードのチュートリアル
Dice Roller サンプル アプリでは、ユーザーにサイコロが表示され、それをロールするボタンが表示されます。 サイコロがロールされると、Live Share SDK は Fluid Framework を使用してクライアント間でデータを同期するため、全員が同じ結果を確認できます。 データを同期するには、 app.js ファイルで次の手順を実行します。
アプリケーションを設定します。
まず、必要なモジュールをインポートします。 このサンプルでは、 Live Share SDK の LiveState DDS と LiveShareClient を 使用します。 このサンプルでは 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
を選択したときに何が起こるかを最初に変更します。 ボタンは、ローカル状態を直接更新する代わりに、diceState
にstate
値として格納されている数値を更新します。 新しい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 トンネルを作成する
ngrok をダウンロードします。
ngrok を使用して、ポート 8080 を使用してトンネルを作成します。 次のコマンドを実行します。
ngrok http 8080 --host-header=localhost
新しい ngrok ターミナルが新しいURL (たとえば
https:...ngrok.io
)で開きます。 新しい URL は、アプリを指すトンネルであり、アプリでmanifest.json
更新する必要があります。
Teams にアップロードするアプリ パッケージを作成する
コンピューターの Dice Roller サンプル フォルダー
live-share-sdk\samples\javascript\01.dice-roller
に移動します。 GitHub の Dice Roller サンプルから manifest.json を確認することもできます。manifest.json を開き、構成 URL を更新します。
https://<<BASE_URI_DOMAIN>>
を ngrok の http エンドポイントに置き換えます 。次のシナリオでは、これらのプロパティを更新できます。
-
developer.name
を自分の名前に設定します。 -
developer.websiteUrl
を Web サイトで更新します。 -
developer.privacyUrl
をプライバシー ポリシーを使用して更新します。 -
developer.termsOfUseUrl
の使用条件を更新します。
-
manifest.zip
を作成するマニフェスト フォルダーの内容を zip 化します。manifest.zip
にmanifest.json
ソース ファイル、color
アイコン、およびoutline
アイコンのみが含まれていることを確認します。- Windowsで、
.\manifest
ディレクトリ内のすべてのファイルを選択し、圧縮します。
注:
- 含まれているフォルダーを圧縮しないでください。
- zip ファイルにわかりやすい名前を付けます。 たとえば、「
DiceRollerLiveShare
」のように入力します。
マニフェストの詳細については、「Teams マニフェストのドキュメント」を参照してください
- Windowsで、
カスタム アプリを会議にアップロードする
Teams を開きます。
Teams の予定表から会議をスケジュールします。 少なくとも 1 人の出席者を会議に招待してください。
会議に参加します。
上部の会議ウィンドウで、[+ アプリ>アプリの管理] を選択します。
[アプリの管理] ウィンドウで、カスタム アプリアップロードを選択します。
- カスタム アプリをアップロードするオプションが表示されない場合は、手順に従ってテナントでカスタム アプリを有効にします。
ボタンを選択し、コンピューターから
manifest.zip
ファイルを選択します。[追加] を選択して、サンプル アプリを会議に追加します。
[+ アプリ] を選択し、[アプリの検索] 検索ボックスに「Dice Roller」と入力します。
会議でアクティブ化するアプリを選択します。
[保存] を選択します。
Dice Roller アプリは、Teams 会議パネルに追加されます。
サイド パネルで、ステージへの共有アイコンを選択します。 Teams 会議の会議ステージでユーザーとのライブ同期を開始します。
これで、会議ステージにダイス ローラーが表示されます。
会議に招待されたユーザーは、会議に参加するときに、ステージ上でアプリを表示できます。
展開
コードをデプロイする準備ができたら、Teams Toolkit または [Teams 開発者ポータル] を使用して、アプリの zip ファイルをプロビジョニングしてアップロードできます。
注:
アプリをアップロードまたは配布する前に、プロビジョニングされた appId を manifest.json
に追加する必要があります。
コード サンプル
サンプルの名前 | 説明 | JavaScript |
---|---|---|
Dice Roller | 接続されているすべてのクライアントがサイコロをふり、結果を表示できるようにします。 | 表示 |
次の手順
関連項目
Platform Docs