使用全息远程处理和 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(含)。 有效优先级为 LowMediumHigh

若要在远程端开始创建数据通道

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

另请参阅