add --listen-open flag for web LAN binding
This commit is contained in:
parent
fa48c81d29
commit
1762fa250f
4 changed files with 43 additions and 5 deletions
10
DEVLOG.md
10
DEVLOG.md
|
|
@ -96,3 +96,13 @@
|
||||||
- Reused Rust simulation engine and instance lifecycle for backend execution.
|
- Reused Rust simulation engine and instance lifecycle for backend execution.
|
||||||
- Rebuilt `index.html` and `data.js` as a modern web dashboard UI backed by Rust APIs.
|
- Rebuilt `index.html` and `data.js` as a modern web dashboard UI backed by Rust APIs.
|
||||||
- Removed legacy client-side simulation engine from the browser path.
|
- Removed legacy client-side simulation engine from the browser path.
|
||||||
|
|
||||||
|
## 2026-02-11 - Open listen option for web mode
|
||||||
|
|
||||||
|
### Scope completed
|
||||||
|
- Added `--listen-open` CLI argument for web mode.
|
||||||
|
- Enforced `--listen-open` usage only when `--web` is present.
|
||||||
|
- Updated web server bind address behavior:
|
||||||
|
- default: `127.0.0.1:9009`
|
||||||
|
- open listen: `0.0.0.0:9009`
|
||||||
|
- Updated startup logs and README usage examples for LAN-accessible mode.
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,16 @@ Then open:
|
||||||
http://127.0.0.1:9009
|
http://127.0.0.1:9009
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Open web mode on all network interfaces (`0.0.0.0:9009`) so other machines can access it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run -- --web --listen-open
|
||||||
|
```
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- The web frontend (`index.html` + `data.js`) now uses Rust backend APIs.
|
- The web frontend (`index.html` + `data.js`) now uses Rust backend APIs.
|
||||||
- Simulation logic runs server-side in Rust (shared with CLI/TUI engine).
|
- Simulation logic runs server-side in Rust (shared with CLI/TUI engine).
|
||||||
|
- `--listen-open` is only valid with `--web` and should be used on trusted networks.
|
||||||
|
|
||||||
### Quick match (headless)
|
### Quick match (headless)
|
||||||
|
|
||||||
|
|
|
||||||
12
src/main.rs
12
src/main.rs
|
|
@ -32,6 +32,9 @@ struct Cli {
|
||||||
#[arg(long, global = true)]
|
#[arg(long, global = true)]
|
||||||
web: bool,
|
web: bool,
|
||||||
|
|
||||||
|
#[arg(long, global = true)]
|
||||||
|
listen_open: bool,
|
||||||
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Option<Commands>,
|
command: Option<Commands>,
|
||||||
}
|
}
|
||||||
|
|
@ -76,6 +79,13 @@ fn main() -> io::Result<()> {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
let base_seed = cli.seed.unwrap_or_else(|| Rng::from_time().next_u64());
|
let base_seed = cli.seed.unwrap_or_else(|| Rng::from_time().next_u64());
|
||||||
|
|
||||||
|
if cli.listen_open && !cli.web {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::InvalidInput,
|
||||||
|
"--listen-open can only be used with --web",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if cli.web {
|
if cli.web {
|
||||||
if cli.command.is_some() {
|
if cli.command.is_some() {
|
||||||
return Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
|
|
@ -83,7 +93,7 @@ fn main() -> io::Result<()> {
|
||||||
"--web cannot be combined with subcommands",
|
"--web cannot be combined with subcommands",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return run_web_server(base_seed, cli.speed);
|
return run_web_server(base_seed, cli.speed, cli.listen_open);
|
||||||
}
|
}
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
|
|
|
||||||
19
src/web.rs
19
src/web.rs
|
|
@ -457,17 +457,28 @@ async fn api_export_csv(path: web::Path<usize>, state: web::Data<SharedState>) -
|
||||||
.body(csv)
|
.body(csv)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_web_server(base_seed: u64, speed: Speed) -> io::Result<()> {
|
pub fn run_web_server(base_seed: u64, speed: Speed, listen_open: bool) -> io::Result<()> {
|
||||||
let shared = SharedState {
|
let shared = SharedState {
|
||||||
inner: Arc::new(Mutex::new(WebState::new(base_seed, speed))),
|
inner: Arc::new(Mutex::new(WebState::new(base_seed, speed))),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ticker = shared.clone();
|
let ticker = shared.clone();
|
||||||
|
let bind_host = if listen_open { "0.0.0.0" } else { "127.0.0.1" };
|
||||||
|
let display_host = if listen_open {
|
||||||
|
"<machine-ip>"
|
||||||
|
} else {
|
||||||
|
"127.0.0.1"
|
||||||
|
};
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Starting SoccerCloud web UI at http://127.0.0.1:{WEB_PORT} (seed={base_seed}, speed={})",
|
"Starting SoccerCloud web UI at http://{display_host}:{WEB_PORT} (bound {bind_host}:{WEB_PORT}, seed={base_seed}, speed={})",
|
||||||
speed.label()
|
speed.label(),
|
||||||
);
|
);
|
||||||
|
if listen_open {
|
||||||
|
println!(
|
||||||
|
"Open listen enabled: accessible from other machines on your network at http://<machine-ip>:{WEB_PORT}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
actix_web::rt::System::new().block_on(async move {
|
actix_web::rt::System::new().block_on(async move {
|
||||||
actix_web::rt::spawn(async move {
|
actix_web::rt::spawn(async move {
|
||||||
|
|
@ -507,7 +518,7 @@ pub fn run_web_server(base_seed: u64, speed: Speed) -> io::Result<()> {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.bind(("127.0.0.1", WEB_PORT))?
|
.bind((bind_host, WEB_PORT))?
|
||||||
.run()
|
.run()
|
||||||
.await
|
.await
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue