WebSocket Proxy Setup#
When using CloudXR.js with HTTPS hosting (for development or production), you need a WebSocket proxy with TLS support to establish secure connections from the browser to the CloudXR Runtime.
Overview#
A WebSocket proxy is required when:
Hosting your web application using HTTPS
Deploying to production environments with SSL certificates
Accessing CloudXR from remote networks or the internet
Using Pico 4 Ultra devices (which require HTTPS)
The proxy acts as a secure gateway, providing TLS termination for WebSocket connections.
Connection Architecture#
Without proxy (HTTP mode):
Browser →ws://<server>:49100→CloudXR Runtime
With proxy (HTTPS mode):
Browser →wss://<proxy>:48322 →CloudXR Runtime (ws://localhost:49100)
Important
When hosting your web application using HTTPS, you must configure a WebSocket proxy and connect using wss://. Browsers block non-secure WebSocket (ws://) connections from secure (HTTPS) pages due to mixed content security policies.
Available Proxy Examples#
CloudXR.js supports the following common deployment scenarios:
Deployment Scenario |
Example Solution |
Setup Complexity |
|---|---|---|
Local development with HTTP |
No proxy needed (direct |
None |
Development/testing with HTTPS |
Docker + HAProxy example |
Low |
Single-server production |
Docker + HAProxy example |
Low |
Kubernetes production |
nginx Ingress example |
Medium |
Example 1: Development Proxy (Docker + HAProxy)#
This example uses HAProxy in a Docker container for HTTPS development and single-server deployments.
Quick Start#
Build the proxy image:
cd proxy docker build -t cloudxr-wss-proxy .
Run the proxy:
docker run -d --name wss-proxy \ --network host \ -e BACKEND_HOST=localhost \ -e BACKEND_PORT=49100 \ -e PROXY_PORT=48322 \ cloudxr-wss-proxy
View logs:
docker logs -f wss-proxy
Configuration Options#
Variable |
Default |
Description |
|---|---|---|
|
|
CloudXR Runtime hostname or IP. |
|
|
CloudXR Runtime WebSocket signaling port. |
|
|
TLS proxy listening port. |
|
|
Time between backend health checks. |
|
|
Consecutive successful checks to mark backend up. |
|
|
Consecutive failed checks to mark backend down. |
Using Custom Certificates#
If you have your own TLS certificate, combine certificate and key into a PEM and mount it:
cat your-cert.crt your-key.key > server.pem
docker run -d --name wss-proxy \
--network host \
-v /path/to/server.pem:/usr/local/etc/haproxy/certs/server.pem:ro \
-e BACKEND_HOST=localhost \
-e BACKEND_PORT=49100 \
-e PROXY_PORT=48322 \
cloudxr-wss-proxy
Managing the Proxy#
docker stop wss-proxy
docker start wss-proxy
docker stop wss-proxy
docker rm wss-proxy
docker stop wss-proxy
docker rm wss-proxy
docker volume rm cloudxr-proxy-certs
Note
To persist self-signed certificates across container restarts, mount a Docker volume:
-v cloudxr-proxy-certs:/usr/local/etc/haproxy/certs.
Common Issues#
Connection refused at startup: Expected while CloudXR Runtime is still initializing.
Certificate warnings: Trust the proxy certificate on the headset/browser before connecting.
Firewall blocking: Ensure proxy TCP port (default
48322) is open.
Example 2: Production Proxy (Kubernetes + nginx)#
For Kubernetes deployments, use nginx Ingress with TLS termination and WebSocket routing.
Typical setup flow:
Create TLS secret.
Deploy nginx proxy service/config.
Configure Ingress for HTTPS + WebSocket traffic.
Validate endpoint, then connect clients using
wss://.
For CloudXR.js path-based proxy routing behavior, see Session API.
Firewall Configuration#
Refer to Ports and Firewalls for required ports and firewall configuration instructions.