Add basic TCP.

This commit is contained in:
2026-04-25 22:50:55 +02:00
parent 4eac555ed4
commit 0636305db5
3 changed files with 69 additions and 2 deletions

View File

@@ -20,8 +20,6 @@ async fn main() {
log::set_max_level(log::LevelFilter::Info);
info!("Starting Bioz Impedance Visualizer...");
let rt = Runtime::new().expect("Unable to create Runtime");
// Enter the runtime so that `tokio::spawn` is available immediately.
// let _enter = rt.enter();
@@ -52,7 +50,15 @@ async fn main() {
// Log thread
tokio::spawn(async move { log_data(log_rx, gui_logging_state_1).await });
// TCP command server in separate thread
let rt = Runtime::new().expect("Unable to create Runtime");
let tcp_run_impedancemeter_tx = run_impedancemeter_tx_clone.clone();
std::thread::spawn(move || {
rt.block_on(bioz_host_rs::tcp::tcp_command_server(tcp_run_impedancemeter_tx));
});
// Execute the runtime in its own thread.
let rt = Runtime::new().expect("Unable to create Runtime");
std::thread::spawn(move || {
rt.block_on(communicate_with_hardware(
run_impedancemeter_rx,

View File

@@ -3,6 +3,7 @@
pub mod client;
pub mod app;
pub mod communication;
pub mod tcp;
pub mod plot;
pub mod signals;
pub mod logging;

60
src/tcp.rs Normal file
View File

@@ -0,0 +1,60 @@
use tokio::net::TcpListener;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter};
use tokio::sync::mpsc::Sender;
use crate::signals::StartStopSignal;
pub async fn tcp_command_server(tx: Sender<StartStopSignal>) {
let listener = TcpListener::bind("127.0.0.1:12345").await.unwrap();
println!("TCP command server listening on 12345");
loop {
let (socket, addr) = listener.accept().await.unwrap();
println!("Client connected: {:?}", addr);
let tx = tx.clone();
tokio::spawn(async move {
let (reader, writer) = socket.into_split();
let mut reader = BufReader::new(reader);
let mut writer = BufWriter::new(writer);
let mut lines = reader.lines();
while let Ok(Some(line)) = lines.next_line().await {
println!("Received: {}", line);
match parse_command(&line) {
Some(signal) => {
if tx.send(signal).await.is_ok() {
let _ = writer.write_all(b"OK\n").await;
} else {
let _ = writer.write_all(b"ERR internal channel failure\n").await;
break;
}
}
None => {
let _ = writer.write_all(b"ERR unknown command\n").await;
}
}
let _ = writer.flush().await;
}
println!("Client disconnected: {:?}", addr);
});
}
}
fn parse_command(line: &str) -> Option<StartStopSignal> {
let parts: Vec<&str> = line.split_whitespace().collect();
match parts.as_slice() {
["STOP"] => Some(StartStopSignal::Stop),
_ => {
eprintln!("Unknown command: {}", line);
None
}
}
}