Skip to content

Commit e63df28

Browse files
committed
fix[client]: Exit WebXR when failed to connect or streaming error
1 parent 8a61d96 commit e63df28

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

deps/cloudxr/webxr_client/helpers/react/CloudXRComponent.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ interface CloudXRComponentProps {
5858
/** Callback fired when an error occurs. Receives error message string. */
5959
onError?: (error: string) => void;
6060

61+
/**
62+
* Called when CloudXR fails to connect or streaming stops with an error.
63+
* Use this to end the immersive WebXR session (same as the user pressing Disconnect).
64+
*/
65+
onExitImmersiveXR?: () => void;
66+
6167
/** Callback fired when CloudXR session is created or destroyed. Receives session instance or null. */
6268
onSessionReady?: (session: CloudXR.Session | null) => void;
6369

@@ -91,6 +97,7 @@ export default function CloudXRComponent({
9197
applicationName,
9298
onStatusChange,
9399
onError,
100+
onExitImmersiveXR,
94101
onSessionReady,
95102
onServerAddress,
96103
onRenderPerformanceMetrics,
@@ -101,6 +108,8 @@ export default function CloudXRComponent({
101108
const { session } = useXR();
102109
// React reference to the CloudXR session that persists across re-renders.
103110
const cxrSessionRef = useRef<CloudXR.Session | null>(null);
111+
const onExitImmersiveXRRef = useRef(onExitImmersiveXR);
112+
onExitImmersiveXRRef.current = onExitImmersiveXR;
104113

105114
// Metrics trackers for averaging performance metrics
106115
// Use prop values if provided, otherwise use defaults
@@ -192,6 +201,7 @@ export default function CloudXRComponent({
192201
} catch (error) {
193202
onStatusChange?.(false, 'Configuration Error');
194203
onError?.(`Proxy configuration failed: ${error}`);
204+
onExitImmersiveXRRef.current?.();
195205
return;
196206
}
197207

@@ -267,6 +277,7 @@ export default function CloudXRComponent({
267277
if (error.reasonCode !== undefined) {
268278
console.debug('Stop reason code:', error.reasonCode);
269279
}
280+
onExitImmersiveXRRef.current?.();
270281
} else {
271282
console.debug('CloudXR session stopped');
272283
onStatusChange?.(false, 'Disconnected');
@@ -304,6 +315,7 @@ export default function CloudXRComponent({
304315
} catch (error) {
305316
onStatusChange?.(false, 'Session Creation Failed');
306317
onError?.(`Failed to create CloudXR session: ${error}`);
318+
onExitImmersiveXRRef.current?.();
307319
return;
308320
}
309321

@@ -323,9 +335,20 @@ export default function CloudXRComponent({
323335
onStatusChange?.(false, 'Connection Failed');
324336
// Report error via callback
325337
onError?.('Failed to connect CloudXR session');
326-
// Clean up the failed session
338+
// Best-effort: release SDK resources if connect() threw after createSession(); ignore disconnect failures.
339+
try {
340+
cxrSession.disconnect();
341+
} catch {
342+
// Ignore errors from disconnect().
343+
}
327344
cxrSessionRef.current = null;
345+
onSessionReady?.(null);
346+
onExitImmersiveXRRef.current?.();
328347
}
348+
} else {
349+
onStatusChange?.(false, 'Reference Space Unavailable');
350+
onError?.('Could not obtain an XR reference space for CloudXR');
351+
onExitImmersiveXRRef.current?.();
329352
}
330353
};
331354

deps/cloudxr/webxr_client/src/App.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,7 @@ function App() {
763763
cloudXR2DUI.showError(error);
764764
}
765765
}}
766+
onExitImmersiveXR={handleDisconnect}
766767
onSessionReady={setCloudXRSession}
767768
onServerAddress={setServerAddress}
768769
onRenderPerformanceMetrics={handleRenderPerformanceMetrics}

0 commit comments

Comments
 (0)