確立されているリモート処理接続経由でカスタム データを送信するには、カスタム データ チャネルを使用します。
重要
カスタム データ チャネルでは、2 つのカスタム アプリ間の通信が許可されるため、カスタム リモート アプリとカスタム プレーヤー アプリが必要です。
ヒント
単純なピンポンの例が Holographic Remoting のサンプルの GitHub リポジトリ内のリモートとプレーヤーのサンプルにあります。 SampleRemoteApp.h/SamplePlayerMain.h ファイル内の #define ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE
のコメントを解除して、このサンプル コードを有効にしてください。
カスタム データ チャネルを作成する
カスタム データ チャネルを作成するには、次のフィールドが必要です。
std::recursive_mutex m_customDataChannelLock;
winrt::Microsoft::Holographic::AppRemoting::IDataChannel m_customDataChannel = nullptr;
winrt::Microsoft::Holographic::AppRemoting::IDataChannel::OnDataReceived_revoker m_customChannelDataReceivedEventRevoker;
winrt::Microsoft::Holographic::AppRemoting::IDataChannel::OnClosed_revoker m_customChannelClosedEventRevoker;
接続が正常に確立されたら、リモート側またはプレーヤー側のどちらか、あるいはその両方から新しいデータ チャネルを作成できます。 RemoteContext と PlayerContext はどちらも、データ チャネルを作成するための CreateDataChannel()
メソッドを提供します。 最初のパラメーターは、後の操作でデータ チャネルを識別するために使用されるチャネル ID です。 2 番目のパラメーターは、このチャネルのデータが、どの優先順位でもう一方の側に転送されるかを指定する優先順位です。 リモート側の有効なチャネル ID は 0 から 63 までです。 プレーヤー側の有効なチャネル ID は 64 から 127 までです。 有効な優先順位は Low
、Medium
、または High
です。
リモート側でデータ チャネルの作成を開始するには、次のようにします。
// Valid channel ids for channels created on the remote side are 0 up to and including 63
m_remoteContext.CreateDataChannel(0, DataChannelPriority::Low);
プレーヤー側でデータ チャネルの作成を開始するには、次のようにします。
// Valid channel ids for channels created on the player side are 64 up to and including 127
m_playerContext.CreateDataChannel(64, DataChannelPriority::Low);
Note
新しいカスタム データ チャネルを作成するには、1 つの側 (リモートまたはプレーヤーのどちらか) だけが CreateDataChannel
メソッドを呼び出す必要があります。
カスタム データ チャネルのイベントの処理
カスタム データ チャネルを確立するには、OnDataChannelCreated
イベントを (プレーヤー側とリモート側の両方で) 処理する必要があります。 これは、ユーザー データ チャネルがどちらかの側で作成されたときにトリガーされ、このチャネル経由でデータを送受信するために使用できる IDataChannel
オブジェクトを提供します。
OnDataChannelCreated
イベントにリスナーを登録するには、次のようにします。
m_onDataChannelCreatedEventRevoker = m_remoteContext.OnDataChannelCreated(winrt::auto_revoke,
[this](const IDataChannel& dataChannel, uint8_t channelId)
{
std::lock_guard lock(m_customDataChannelLock);
m_customDataChannel = dataChannel;
// Register to OnDataReceived and OnClosed event of the data channel here, see below...
});
データが受信されたときに通知を受け取るには、OnDataChannelCreated
ハンドラーによって提供される IDataChannel
オブジェクトの OnDataReceived
イベントに登録します。 データ チャネルか閉じられたときに通知を受け取るには、OnClosed
イベントに登録します。
m_customChannelDataReceivedEventRevoker = m_customDataChannel.OnDataReceived(winrt::auto_revoke,
[this]()
{
// React on data received via the custom data channel here.
});
m_customChannelClosedEventRevoker = m_customDataChannel.OnClosed(winrt::auto_revoke,
[this]()
{
// React on data channel closed here.
std::lock_guard lock(m_customDataChannelLock);
if (m_customDataChannel)
{
m_customDataChannel = nullptr;
}
});
データの送信
カスタム データ チャネル経由でデータを送信するには、IDataChannel::SendData()
メソッドを使用します。 最初のパラメーターは、送信されるデータへの winrt::array_view<const uint8_t>
です。 2 番目のパラメーターでは、もう一方の側が受信を確認するまで、そのデータを再送信するかどうかを指定します。
重要
ネットワークの状態が悪い場合は、同じデータ パケットが複数回到着する可能性があります。 受信側のコードでは、この状況に対応できる必要があります。
uint8_t data[] = {1};
m_customDataChannel.SendData(data, true);
カスタム データ チャネルを閉じる
カスタム データ チャネルを閉じるには、IDataChannel::Close()
メソッドを使用します。 カスタム データ チャネルが閉じられたら、両方の側が OnClosed
イベントから通知を受け取ります。
m_customDataChannel.Close();