使用全息远程处理和 Windows Mixed Reality API 建立自定义数据信道
使用自定义数据通道通过已建立的远程处理连接发送自定义数据。
重要
自定义数据通道需要自定义远程应用和自定义播放器应用,因为它允许在两个自定义应用之间进行通信。
提示
可在全息远程处理示例 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。 第二个参数是将此通道的数据传输到另一端时需遵循的优先级。 在远程端,有效通道 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);
注意
只需要在一端(远程或播放器)调用 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>
。 第二个参数指定应重新发送数据的位置,直到另一端确认接收。
重要
如果网络状况不佳,则同一个数据包可能会多次抵达。 接收代码必须能够处理这种情况。
uint8_t data[] = {1};
m_customDataChannel.SendData(data, true);
关闭自定义数据通道
若要关闭自定义数据通道,请使用 IDataChannel::Close()
方法。 自定义数据通道关闭后,OnClosed
事件会通知两端。
m_customDataChannel.Close();