Files
unshell/examples/protocol/remote_shell_endpoint.rs
T

58 lines
1.8 KiB
Rust
Raw Normal View History

//! Remote shell endpoint example.
//!
//! This binary acts as the single remote-shell endpoint process. It connects to the controller
//! example over TCP, feeds inbound frames into the `ProcedureRuntime`, and flushes any resulting
//! protocol frames back to the controller.
2026-04-25 14:41:00 -06:00
use std::error::Error;
use std::net::TcpStream;
2026-04-25 15:35:08 -06:00
use std::sync::mpsc::RecvTimeoutError;
2026-04-25 14:41:00 -06:00
use std::time::Duration;
use unshell::leaves::remote_shell;
2026-04-26 13:54:44 -06:00
use unshell::protocol::tree::{Ingress, ProcedureRuntime, ProtocolEndpoint};
2026-04-25 14:41:00 -06:00
fn main() -> Result<(), Box<dyn Error>> {
let mut stream = TcpStream::connect(remote_shell::endpoint::LISTEN_ADDR)?;
let frame_rx = remote_shell::endpoint::spawn_frame_reader(stream.try_clone()?);
2026-04-26 13:54:44 -06:00
let endpoint = ProtocolEndpoint::new(
agent_path(),
Some(Vec::new()),
Vec::new(),
vec![remote_shell::endpoint::RemoteShellEndpoint::protocol_leaf_spec()],
);
let mut runtime = ProcedureRuntime::<
remote_shell::endpoint::RemoteShellEndpoint,
remote_shell::endpoint::Open,
>::new(
endpoint,
remote_shell::endpoint::RemoteShellEndpoint::default(),
);
2026-04-25 14:41:00 -06:00
println!(
"connected to controller at {}",
remote_shell::endpoint::LISTEN_ADDR
);
2026-04-25 14:41:00 -06:00
loop {
match frame_rx.recv_timeout(Duration::from_millis(25)) {
Ok(result) => {
let frame = result?;
2026-04-25 15:35:08 -06:00
let outcome = runtime.receive(&Ingress::Parent, frame)?;
remote_shell::endpoint::write_frames(&mut stream, &outcome.frames)?;
2026-04-25 14:41:00 -06:00
}
Err(RecvTimeoutError::Timeout) => {}
Err(RecvTimeoutError::Disconnected) => break,
}
2026-04-25 15:35:08 -06:00
let outcome = runtime.poll()?;
remote_shell::endpoint::write_frames(&mut stream, &outcome.frames)?;
2026-04-25 14:41:00 -06:00
}
Ok(())
}
2026-04-26 13:54:44 -06:00
fn agent_path() -> Vec<String> {
vec![String::from("agent")]
}