Benutzerdefinierte Datenkanäle mit Holographic Remoting und der OpenXR-API

Verwenden Sie benutzerdefinierte Datenkanäle, um benutzerdefinierte Daten über eine hergestellte Remotingverbindung zu senden.

Wichtig

Benutzerdefinierte Datenkanäle erfordern eine benutzerdefinierte Remote-App und eine benutzerdefinierte Player-App. Dies ermöglicht die Kommunikation zwischen den beiden benutzerdefinierten Apps.

Tipp

Ein einfaches Ping-Pong-Beispiel finden Sie in den Remote- und Playerbeispielen im GitHub-Repository holographic Remoting samples . Heben Sie die Auskommentierung #define ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE in den Dateien OpenXrProgramm.cpp und SamplePlayerMain.h auf, um den Beispielcode zu aktivieren.

Erstellen eines benutzerdefinierten Datenkanals

Ein benutzerdefinierter Datenkanal wird durch das XrRemotingDataChannelMSFT Handle definiert:

XrRemotingDataChannelMSFT m_userDataChannel;

Nachdem eine Verbindung erfolgreich hergestellt wurde, können neue Datenkanäle über die xrCreateRemotingDataChannelMSFT Funktion erstellt werden:

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

Benutzerdefinierte Datenkanäle können aus dem Player und der Remoteanwendung erstellt werden, auch wenn sich die Laufzeiten unterscheiden. Wenn ein Datenkanal von der Playerseite erstellt wird, wird die Remoteseite mit der XrEventDataRemotingDataChannelCreatedMSFT Ereignisstruktur benachrichtigt:

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

Der Anfangszustand XrRemotingDataChannelStatusMSFT nach dem Aufruf xrCreateRemotingDataChannelMSFT ist XR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFT. Nachdem der Datenkanal vollständig eingerichtet wurde, wechselt der Zustand des Kanals zu XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT. Die XrEventDataRemotingDataChannelOpenedMSFT Ereignisstruktur wird in der Ereigniswarteschlange platziert, wenn der Zustand eines zuvor erstellten Datenkanals von zu XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFTXR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFT wechselt.

Abrufen des Kanalzustands

Die xrGetRemotingDataChannelStateMSFT -Funktion kann verwendet werden, um den Datenkanalstatus abzufragen:

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

Senden von Daten

Wenn der Kanal geöffnet ist, wird die xrSendRemotingDataMSFT Funktion verwendet, um Daten an die Spielerseite zu senden:

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

Hinweis

Die Daten, die Sie über einen benutzerdefinierten Datenkanal senden, teilen sich die Bandbreite mit anderen Datenkanälen, die Holographic Remoting verwendet.

Abrufen von Daten

Jedes Mal, wenn Daten über einen Datenkanal eingehen, wird eine XrEventDataRemotingDataChannelDataReceivedMSFT Ereignisstruktur in die Ereigniswarteschlange eingefügt. Empfangene Pakete können mit der xrRetrieveRemotingDataMSFT -Funktion abgerufen werden:

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

Löschen eines Datenkanals

Sie können einen Datenkanal mit xrDestroyRemotingDataChannelMSFTzerstören:

CHECK_XRCMD(m_extensions.xrDestroyRemotingDataChannelMSFT(m_userDataChannel));

Das XrRemotingDataChannelMSFT Handle ist nach dem xrDestroyRemotingDataChannelMSFT Aufruf ungültig, und das Datenkanalhandle darf danach nicht mehr verwendet werden.

Wird XrEventDataRemotingDataChannelClosedMSFT in der Ereigniswarteschlange platziert, falls der Datenkanal von der Spielerseite geschlossen oder zerstört wird. Der Datenkanalzustand wechselt zu XR_REMOTING_DATA_CHANNEL_STATUS_CLOSED_MSFT. Für einen geschlossenen Datenkanal bleibt das XrRemotingDataChannelMSFT Handle gültig.

Weitere Informationen