# 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.