Niestandardowe kanały danych za pomocą komunikacji zdalnie holograficznej i interfejsu API OpenXR

Użyj niestandardowych kanałów danych, aby wysyłać niestandardowe dane za pośrednictwem ustanowionego połączenia komunikacji wirtualnej.

Ważne

Niestandardowe kanały danych wymagają niestandardowej aplikacji zdalnej i niestandardowej aplikacji odtwarzacza. Umożliwia to komunikację między dwiema aplikacjami niestandardowymi.

Porada

Prosty przykład ping-pong można znaleźć w zdalnych i odtwarzaczach przykładów w repozytorium github holographic Remoting samples. Usuń komentarz #define ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE wewnątrz plików OpenXrProgramm.cpp i SamplePlayerMain.h, aby włączyć przykładowy kod.

Uwaga

Szczegółową specyfikację można znaleźć w repozytorium github przykładów holographic Remoting.

Tworzenie niestandardowego kanału danych

Niestandardowy kanał danych jest definiowany XrRemotingDataChannelMSFT przez uchwyt:

XrRemotingDataChannelMSFT m_userDataChannel;

Po pomyślnym nawiązaniu połączenia można utworzyć nowe kanały danych za pośrednictwem xrCreateRemotingDataChannelMSFT funkcji:

XrRemotingDataChannelCreateInfoMSFT channelInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_DATA_CHANNEL_CREATE_INFO_MSFT)};
channelInfo.channelId = 0;
channelInfo.channelPriority = XR_REMOTING_DATA_CHANNEL_PRIORITY_LOW_MSFT;
CHECK_XRCMD(m_extensions.xrCreateRemotingDataChannelMSFT(m_instance.Get(), m_systemId, &channelInfo, &m_userDataChannel));

Niestandardowe kanały danych można tworzyć na podstawie odtwarzacza i aplikacji zdalnej, nawet jeśli środowiska uruchomieniowe są inne. Jeśli kanał danych zostanie utworzony po stronie odtwarzacza, strona zdalna zostanie powiadomiona o XrEventDataRemotingDataChannelCreatedMSFT strukturze zdarzeń:

XrEventDataBuffer eventData{};
while (pollEvent(eventData)) 
{
    switch (eventData.type) 
    {
        case XR_TYPE_EVENT_DATA_REMOTING_DATA_CHANNEL_CREATED_MSFT: 
        {
            auto channelCreatedEventData = reinterpret_cast<const XrEventDataRemotingDataChannelCreatedMSFT*>(&eventData);
            m_userDataChannel = channelCreatedEventData->channel;
            break;
        }
    }
}

XrRemotingDataChannelStatusMSFT Początkowy stan po wywołaniu xrCreateRemotingDataChannelMSFT to XR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFT. Po pełnym ustanowieniu kanału danych stan kanału przełącza się na XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT. Struktura XrEventDataRemotingDataChannelOpenedMSFT zdarzeń jest umieszczana w kolejce zdarzeń, gdy stan wcześniej utworzonego kanału danych przełącza się z XR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFT na XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT.

Pobieranie stanu kanału

Funkcja xrGetRemotingDataChannelStateMSFT może służyć do wykonywania zapytań dotyczących stanu kanału danych:

XrRemotingDataChannelStateMSFT channelState{static_cast<XrStructureType>(XR_TYPE_REMOTING_DATA_CHANNEL_STATE_MSFT)};
CHECK_XRCMD(m_extensions.xrGetRemotingDataChannelStateMSFT(m_userDataChannel, &channelState));

Wysyłanie danych

Jeśli kanał jest otwarty, xrSendRemotingDataMSFT funkcja jest używana do wysyłania danych do strony odtwarzacza:

if (channelState.connectionStatus == XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT) {
    // Only send the packet if the send queue is smaller than 1MiB
    if (channelState.sendQueueSize >= 1 * 1024 * 1024) {
        return;
    }
    uint8_t data[] = {1};

    XrRemotingDataChannelSendDataInfoMSFT sendInfo{
        static_cast<XrStructureType>(XR_TYPE_REMOTING_DATA_CHANNEL_SEND_DATA_INFO_MSFT)};
    sendInfo.data = data;
    sendInfo.size = sizeof(data);
    sendInfo.guaranteedDelivery = true;
    CHECK_XRCMD(m_extensions.xrSendRemotingDataMSFT(m_userDataChannel, &sendInfo));
}

Uwaga

Dane wysyłane za pośrednictwem niestandardowego kanału danych współdzielą przepustowość z innymi kanałami danych holographic Remoting.

Pobieranie danych

Za każdym razem, gdy dane docierają za pośrednictwem kanału danych, XrEventDataRemotingDataChannelDataReceivedMSFT struktura zdarzeń jest umieszczana w kolejce zdarzeń. Odebrane pakiety można pobrać za pomocą xrRetrieveRemotingDataMSFT funkcji:

XrEventDataBuffer eventData{};
while (pollEvent(eventData)) 
{
    switch (eventData.type) 
    {
        case XR_TYPE_EVENT_DATA_REMOTING_DATA_CHANNEL_DATA_RECEIVED_MSFT: 
        {
            auto dataReceivedEventData = reinterpret_cast<const XrEventDataRemotingDataChannelDataReceivedMSFT*>(&eventData);
            std::vector<uint8_t> packet(dataReceivedEventData->size);
            uint32_t dataBytesCount;
            CHECK_XRCMD(m_extensions.xrRetrieveRemotingDataMSFT(dataReceivedEventData->channel,
                                                                dataReceivedEventData->packetId,
                                                                static_cast<uint32_t>(packet.size()),
                                                                &dataBytesCount,
                                                                packet.data()));
            break;
        }
    }
}

Niszczenie kanału danych

Kanał danych można zniszczyć za pomocą polecenia xrDestroyRemotingDataChannelMSFT:

CHECK_XRCMD(m_extensions.xrDestroyRemotingDataChannelMSFT(m_userDataChannel));

Uchwyt XrRemotingDataChannelMSFT jest nieprawidłowy po wywołaniu xrDestroyRemotingDataChannelMSFT , a uchwyt kanału danych nie może być używany później.

Element XrEventDataRemotingDataChannelClosedMSFT zostanie umieszczony w kolejce zdarzeń w przypadku zamknięcia lub zniszczenia kanału danych po stronie odtwarzacza. Stan kanału danych przełącza się na XR_REMOTING_DATA_CHANNEL_STATUS_CLOSED_MSFT. W przypadku zamkniętego kanału XrRemotingDataChannelMSFT danych uchwyt pozostaje prawidłowy.

Zobacz też