Buggy but mostly working std implementation
This commit is contained in:
commit
13610f3470
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
||||
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "kissdummy"
|
||||
version = "0.1.0"
|
||||
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "kissdummy"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
134
src/main.rs
Normal file
134
src/main.rs
Normal file
@ -0,0 +1,134 @@
|
||||
use std::io::Read;
|
||||
use std::io::Write;
|
||||
use std::net::TcpListener;
|
||||
use std::net::TcpStream;
|
||||
|
||||
mod message_bus {
|
||||
use std::sync::mpsc::{channel, Receiver, SendError, Sender};
|
||||
|
||||
pub struct MsgSender(Sender<Msg>);
|
||||
impl MsgSender {
|
||||
pub fn send(&self, data: Vec<u8>) -> Result<(), SendError<Msg>> {
|
||||
self.0.send(Msg::Data(data))
|
||||
}
|
||||
}
|
||||
//pub struct MsgReceiver(Receiver<Vec<u8>>);
|
||||
pub type MsgReceiver = Receiver<Vec<u8>>;
|
||||
|
||||
pub enum Msg {
|
||||
Data(Vec<u8>),
|
||||
Subscribe(Sender<Vec<u8>>),
|
||||
}
|
||||
|
||||
pub struct MessageBus {
|
||||
input: Sender<Msg>,
|
||||
//outputs: Vec<Sender<Msg>>,
|
||||
}
|
||||
|
||||
fn output_loop(main_rx: Receiver<Msg>) {
|
||||
let mut outputs: Vec<Sender<Vec<u8>>> = vec![];
|
||||
loop {
|
||||
match main_rx.recv() {
|
||||
Ok(Msg::Data(data)) => {
|
||||
let mut i = 0;
|
||||
while i < outputs.len() {
|
||||
if outputs[i].send(data.clone()).is_err() {
|
||||
outputs.swap_remove(i);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Msg::Subscribe(sender)) => {
|
||||
outputs.push(sender);
|
||||
}
|
||||
Err(_e) => {
|
||||
println!("Error bus died")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl MessageBus {
|
||||
pub fn new() -> Self {
|
||||
let (input, input_rx) = channel();
|
||||
|
||||
std::thread::spawn(move || output_loop(input_rx));
|
||||
Self { input, /*outputs*/ }
|
||||
}
|
||||
|
||||
pub fn subscribe(&self) -> (MsgSender, Receiver<Vec<u8>>) {
|
||||
let (tx, rx) = channel();
|
||||
let input = self.input.clone();
|
||||
|
||||
input.send(Msg::Subscribe(tx)).unwrap();
|
||||
(MsgSender(input), rx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let bus = message_bus::MessageBus::new();
|
||||
|
||||
/*
|
||||
let (tx1, rx1) = bus.subscribe();
|
||||
let (tx2, rx2) = bus.subscribe();
|
||||
|
||||
let payload = "Hello world!".to_string().as_bytes().to_vec();
|
||||
|
||||
tx1.send(payload.clone()).unwrap();
|
||||
assert_eq!(rx2.recv().unwrap(), rx1.recv().unwrap());
|
||||
|
||||
println!("sleeping 5");
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
println!("dropping rx2 and sleeping 5");
|
||||
drop(rx2);
|
||||
drop(tx2);
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
println!("sending payload and sleeping 5");
|
||||
tx1.send(payload.clone()).unwrap();
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
println!("creating new rx2 and sleeping 5");
|
||||
let (tx2, rx2) = bus.subscribe();
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
println!("sending payload and sleeping 5");
|
||||
tx2.send(payload.clone()).unwrap();
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
*/
|
||||
|
||||
let listener = TcpListener::bind("127.0.0.1:8001")?;
|
||||
for stream in listener.incoming() {
|
||||
match stream {
|
||||
Ok(tx_tcp) => {
|
||||
let (tx_bus, rx_bus) = bus.subscribe();
|
||||
let rx_tcp = tx_tcp.try_clone().unwrap();
|
||||
|
||||
std::thread::spawn(move || publish_thread(rx_tcp, tx_bus));
|
||||
|
||||
std::thread::spawn(move || consume_thread(tx_tcp, rx_bus));
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Error accepting connection: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn publish_thread(mut rx_tcp: TcpStream, tx_bus: message_bus::MsgSender) {
|
||||
let mut buffer = vec![0_u8; 2048];
|
||||
while let Ok(len) = rx_tcp.read(&mut buffer) {
|
||||
let data = buffer[..len].to_vec();
|
||||
if tx_bus.send(data).is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn consume_thread(mut tx_tcp: TcpStream, rx_bus: message_bus::MsgReceiver) {
|
||||
while let Ok(data) = rx_bus.recv() {
|
||||
if tx_tcp.write_all(&data).is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user