# local_rpc_bridge **Repository Path**: qoder/local_rpc_bridge ## Basic Information - **Project Name**: local_rpc_bridge - **Description**: 本地web页面代码执行服务,将本地脚本注入到页面中,然后通过接口执行任意页面中的方法,用于给AI提供页面控制演示的功能。 - **Primary Language**: Go - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-17 - **Last Updated**: 2026-07-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # local_rpc A tiny local **JS eval bridge** for driving a web page from outside the browser. - Go binary starts an HTTP + WebSocket server bound to `127.0.0.1:18080`. - A page (e.g. the web UI embedded in a UE digital-twin) connects with two lines. - Methods are defined as plain `function NAME(...)` declarations in `methods/*.js`. - Any external caller (shell, Python, UE Blueprint HTTP node, etc.) POSTs to `/api/call/{method}` and gets the JS return value back as JSON. ``` [caller] --HTTP POST--> [Go bridge] --WS--> [page eval] | | | <-result----- + | | methods/*.js -> init on connect ``` ## Run ```bash go run . # or with custom bind / methods dir: go run . -addr 127.0.0.1:9090 -methods ./methods ``` ## Wire a page In any HTML page (the UE-embedded webview, a control panel, anything): ```html ``` If the page is itself served from the bridge host, the `__BRIDGE_URL` line can be omitted; the client falls back to `ws://${location.host}/ws`. The client auto-reconnects with exponential backoff. Methods are injected into the page's global scope on connect (and on every `/api/reload`). ## Call methods ```bash # path-style (curl-friendly): body is the args array curl -X POST http://127.0.0.1:18080/api/call/ping -d '["hi"]' # body-style: full JSON envelope (target + timeout_ms supported) curl -X POST http://127.0.0.1:18080/api/call \ -d '{"method":"setCamera","args":[100,200,50,0],"target":"page-1","timeout_ms":5000}' ``` Other endpoints: | Method | Path | Body | |---|---|---| | GET | `/api/methods` | — | | GET | `/api/targets` | — | | POST | `/api/reload` | — re-read `methods/*.js` and re-inject to all pages | | GET | `/bridge.js` | client script | | GET | `/ws?name=foo` | WebSocket upgrade | ## Writing methods Drop a `.js` file in `methods/`. Declare methods as `function NAME(...)`: ```js function setCamera(x, y, z) { window.ue.camera.setLocation(x, y, z); return { ok: true }; } ``` Rules: - Method name is extracted by regex `^\s*function\s+NAME\s*\(`. Only function declarations are discovered; arrow functions and `const fn = ...` won't show up in `/api/methods` and won't be invokable. - The function body runs in the page global scope. Return any JSON-serializable value; throw to surface an error. Promises are awaited. - Call `window.__bridgeLog(...)` to emit a line into the server log. - After editing methods, hit `POST /api/reload` to push them to all connected pages without restarting. ## Multiple pages Each WS connection registers as a target. Pass `?name=foo` on the WS URL to name it explicitly: ```html ``` HTTP calls route via `target` (query or body); without it, the first connected page is used. ## Security Binds to loopback by default. The server sends arbitrary JS to be `eval`'d in the page; do **not** expose it on a public interface, and only point `__BRIDGE_URL` at a bridge you control.