Canali dati personalizzati con Holographic Remoting e l'API OpenXR

Usare canali di dati personalizzati per inviare dati personalizzati tramite una connessione remota stabilita.

Importante

I canali dati personalizzati richiedono un'app remota personalizzata e un'app lettore personalizzata. Ciò consente la comunicazione tra le due app personalizzate.

Suggerimento

Un semplice esempio di ping-pong è disponibile negli esempi remoti e dei giocatori all'interno del repository GitHub degli esempi di Holographic Remoting. Rimuovere il commento #define ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE nei file OpenXrProgramm.cpp e SamplePlayerMain.h per abilitare il codice di esempio.

Nota

La specifica dettagliata è disponibile nel repository GitHub degli esempi di Holographic Remoting.

Creare un canale dati personalizzato

Un canale dati personalizzato viene definito dall'handle XrRemotingDataChannelMSFT :

XrRemotingDataChannelMSFT m_userDataChannel;

Dopo aver stabilito una connessione, è possibile creare nuovi canali dati tramite la xrCreateRemotingDataChannelMSFT funzione :

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

È possibile creare canali di dati personalizzati dal lettore e dall'applicazione remota anche se i runtime sono diversi. Se un canale dati viene creato dal lato lettore, il lato remoto viene notificato con la struttura XrEventDataRemotingDataChannelCreatedMSFT dell'evento:

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;
        }
    }
}

Lo stato XrRemotingDataChannelStatusMSFT iniziale dopo la chiamata xrCreateRemotingDataChannelMSFT è XR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFT. Dopo aver stabilito completamente il canale dati, lo stato del canale passa a XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT. La XrEventDataRemotingDataChannelOpenedMSFT struttura degli eventi viene inserita nella coda degli eventi quando lo stato di un canale dati creato in precedenza passa da XR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFT a XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT.

Ottenere lo stato del canale

La xrGetRemotingDataChannelStateMSFT funzione può essere usata per eseguire query sullo stato del canale dati:

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

Inviare dati

Se il canale è aperto, la xrSendRemotingDataMSFT funzione viene usata per inviare dati al lato lettore:

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));
}

Nota

I dati inviati tramite un canale dati personalizzato condividono la larghezza di banda con altri canali di dati utilizzati da Holographic Remoting.

Recuperare dati

Ogni volta che i dati arrivano tramite un canale dati, una XrEventDataRemotingDataChannelDataReceivedMSFT struttura di eventi viene inserita nella coda degli eventi. I pacchetti ricevuti possono essere recuperati con la xrRetrieveRemotingDataMSFT funzione :

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;
        }
    }
}

Eliminare un canale dati

È possibile eliminare un canale dati con xrDestroyRemotingDataChannelMSFT:

CHECK_XRCMD(m_extensions.xrDestroyRemotingDataChannelMSFT(m_userDataChannel));

L'handle XrRemotingDataChannelMSFT non è valido dopo la xrDestroyRemotingDataChannelMSFT chiamata e l'handle del canale dati non deve essere usato in seguito.

L'oggetto XrEventDataRemotingDataChannelClosedMSFT verrà inserito nella coda degli eventi nel caso in cui il lato lettore chiuda o distruggi il canale dati. Lo stato del canale dati passa a XR_REMOTING_DATA_CHANNEL_STATUS_CLOSED_MSFT. Per un canale dati chiuso, l'handle XrRemotingDataChannelMSFT rimane valido.

Vedere anche