fix: UI auto-detects server port from page origin (#55)

The UI had hardcoded localhost:8080 for HTTP and localhost:8765 for
WebSocket, causing "Backend unavailable" when served from Docker
(port 3000) or any non-default port.

Changes:
- api.config.js: BASE_URL now uses window.location.origin instead
  of hardcoded localhost:8080
- api.config.js: buildWsUrl() uses window.location.host instead of
  hardcoded localhost:8080
- sensing.service.js: WebSocket URL derived from page origin instead
  of hardcoded localhost:8765
- main.rs: Added /ws/sensing route to the HTTP server so WebSocket
  and REST are reachable on a single port

Fixes #55

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruv
2026-03-01 02:09:23 -05:00
parent a0b5506b8c
commit 3b72f35306
3 changed files with 18 additions and 6 deletions

View File

@@ -2091,6 +2091,8 @@ async fn main() {
// Stream endpoints
.route("/api/v1/stream/status", get(stream_status))
.route("/api/v1/stream/pose", get(ws_pose_handler))
// Sensing WebSocket on the HTTP port so the UI can reach it without a second port
.route("/ws/sensing", get(ws_sensing_handler))
// Static UI files
.nest_service("/ui", ServeDir::new(&ui_path))
.layer(SetResponseHeaderLayer::overriding(

View File

@@ -1,7 +1,13 @@
// API Configuration for WiFi-DensePose UI
// Auto-detect the backend URL from the page origin so the UI works whether
// served from Docker (:3000), local dev (:8080), or any other port.
const _origin = (typeof window !== 'undefined' && window.location && window.location.origin)
? window.location.origin
: 'http://localhost:3000';
export const API_CONFIG = {
BASE_URL: 'http://localhost:8080', // Rust sensing server port
BASE_URL: _origin,
API_VERSION: '/api/v1',
WS_PREFIX: 'ws://',
WSS_PREFIX: 'wss://',
@@ -115,8 +121,8 @@ export function buildWsUrl(endpoint, params = {}) {
? API_CONFIG.WSS_PREFIX
: API_CONFIG.WS_PREFIX;
// Match Rust sensing server port
const host = 'localhost:8080';
// Derive host from the page origin so it works on any port (Docker :3000, dev :8080, etc.)
const host = window.location.host;
let url = `${protocol}${host}${endpoint}`;
// Add query parameters

View File

@@ -8,7 +8,11 @@
* always shows something.
*/
const SENSING_WS_URL = 'ws://localhost:8765/ws/sensing';
// Derive WebSocket URL from the page origin so it works on any port
// (Docker :3000, native :8080, etc.)
const _wsProto = (typeof window !== 'undefined' && window.location.protocol === 'https:') ? 'wss:' : 'ws:';
const _wsHost = (typeof window !== 'undefined' && window.location.host) ? window.location.host : 'localhost:3000';
const SENSING_WS_URL = `${_wsProto}//${_wsHost}/ws/sensing`;
const RECONNECT_DELAYS = [1000, 2000, 4000, 8000, 16000];
const MAX_RECONNECT_ATTEMPTS = 10;
const SIMULATION_INTERVAL = 500; // ms