Migrating from CloudXR 5.0 to 6.0#
Overview#
CloudXR 6.0 introduces MessageChannels for client-server communication. Messages are no longer sent directly through Session; instead, you obtain a MessageChannel from the session and send messages through the channel.
Applications that use OmniverseStateManager do not require migration as the underlying API has been updated. Direct session.sendServerMessage() calls must be updated.
Migration time: ~15-30 minutes for typical applications.
API Changes#
Sending Messages#
CloudXR 5.0:
// Direct session messaging
session.sendServerMessage(messageData)
CloudXR 6.0 - Recommended Pattern:
// Use ServerMessageDispatcher (handles channels automatically)
ConfiguratorAppModel.omniverseMessageDispatcher.sendMessage(messageData)
// Or through OmniverseStateManager
asset.stateManager.send(message)
CloudXR 6.0 - Direct Channel Access (advanced):
// For applications needing fine control over channels
guard let channelInfo = session.availableMessageChannels.first,
let channel = session.getMessageChannel(channelInfo) else {
return
}
channel.sendServerMessage(messageData)
Receiving Messages#
CloudXR 5.0:
// ServerMessageDispatcher listened to session.serverMessageStream
for await message in session.serverMessageStream {
listeners.forEach({ $0.onMessageReceived(message: message) })
}
CloudXR 6.0:
// ServerMessageDispatcher manages multiple channels
// Listens to each channel's receivedMessageStream separately
for await message in channel.receivedMessageStream {
listeners.forEach({ $0.onMessageReceived(message: message) })
}
Updated ServerMessageDispatcher#
The ServerMessageDispatcher in CloudXR 6.0 now:
Manages multiple MessageChannels with UUIDs.
Automatically queues messages when channels aren’t ready.
Observes
session.availableMessageChannelsfor lifecycle management.Provides thread-safe operations.
Key change in ConfiguratorAppModel:
public class ConfiguratorAppModel {
public static var omniverseMessageDispatcher = ServerMessageDispatcher()
public var session: Session? {
get { asset.stateManager.session }
set {
asset.stateManager.session = newValue
Self.omniverseMessageDispatcher.session = newValue
Self.omniverseMessageDispatcher.attach(asset.stateManager)
}
}
}
OmniverseStateManager send() method:
// CloudXR 5.0
public func send(_ message: any MessageProtocol) {
guard let session = self.session else { return }
session.sendServerMessage(encodeJSON(message.encodable))
}
// CloudXR 6.0
public func send(_ message: any MessageProtocol) {
guard session != nil else { return }
let messageData = encodeJSON(message.encodable)
if !ConfiguratorAppModel.omniverseMessageDispatcher.sendMessage(messageData) {
Self.logger.error("Failed to send message")
}
}
Migration Checklist#
Update ServerMessageDispatcher
Copy the updated
ServerMessageDispatcher.swiftfrom the CloudXR 6.0 sample.Or implement channel management logic in your existing dispatcher.
Update OmniverseStateManager (if customized)
Replace
session.sendServerMessage()withmessageDispatcher.sendMessage().Add error handling for failed sends.
Update ConfiguratorAppModel (if customized)
Add static
omniverseMessageDispatcherinstance.Update session setter to configure the dispatcher.
Search and replace direct session calls
Replace with
asset.stateManager.send()ormessageDispatcher.sendMessage().
Remove MessageProtocol from AssetCamera (if implemented)
AssetCamerano longer needsMessageProtocolconformance.Remove
isEqualTo()method if present.
Test messaging functionality
Verify variant changes work.
Test camera switching.
Confirm custom messages send/receive correctly.
Check that UI properly waits for server acknowledgments.
Common Issues#
“Channel not ready” warnings
Messages are automatically queued when channels aren’t available.
Ensure
ServerMessageDispatcheris properly initialized with the session.
Multiple channel confusion
Most applications only need one channel (the first available).
messageDispatcher.sendMessage(data, channelUUID: nil)automatically uses first channel.Only specify
channelUUIDif you need to target a specific channel.
Messages not being received
Verify
ServerMessageDispatcheris attached as a listener.Check that
session.availableMessageChannelsis not empty.Ensure server-side channel creation is working.