我想做消息廣播:當其中一個客戶端發送消息時,服務器將它寫入每個套接字。我的主要問題是我無法弄清楚如何發送Vec
到線程。我不能使用Mutex
,因爲這會將其他線程的訪問鎖定到Vec
進行讀取。我無法克隆和發送,因爲無法克隆和發送TcpStream
。這裏是我的嘗試到現在爲止只要其中一個讀取新輸入,我可以維護一個TcpStream的Vec來跨線程寫入它們嗎?
use std::net::{TcpStream, TcpListener};
use std::io::prelude::*;
use std::sync::{Arc, Mutex};
use std::thread;
use std::sync::mpsc::{channel, Receiver};
use std::cell::RefCell;
type StreamSet = Arc<RefCell<Vec<TcpStream>>>;
type StreamReceiver = Arc<Mutex<Receiver<StreamSet>>>;
fn main() {
let listener = TcpListener::bind("0.0.0.0:8000").unwrap();
let mut connection_set: StreamSet = Arc::new(RefCell::new(vec![]));
let mut id = 0;
let (tx, rx) = channel();
let rx = Arc::new(Mutex::new(rx));
for stream in listener.incoming() {
let receiver = rx.clone();
let stream = stream.unwrap();
(*connection_set).borrow_mut().push(stream);
println!("A connection established with client {}", id);
thread::spawn(move || handle_connection(receiver, id));
id += 1;
tx.send(connection_set.clone()).unwrap();
}
}
fn handle_connection(rx: StreamReceiver, id: usize) {
let streams;
{
streams = *(rx.lock().unwrap().recv().unwrap()).borrow();
}
let mut connection = &streams[id];
loop {
let mut buffer = [0; 512];
if let Err(_) = connection.read(&mut buffer) {
break;
};
println!("Request: {}", String::from_utf8_lossy(&buffer[..]));
if let Err(_) = connection.write(&buffer[..]) {
break;
};
if let Err(_) = connection.flush() {
break;
};
}
}
啊謝謝。我實際上對編碼比較陌生,將在下個月完成一年。所以我試圖在使用像tokio這樣的抽象之前盡我所能地自己實現它,所以我明白了底下發生了什麼。我將嘗試實施控制器工作者模型。每個單獨的線程是否有單獨的通道,或者它們是否使用相同的接收器,發送器對? – codeNoob
我期望控制器線程爲每個工作線程有一個唯一的通道向它們發送數據,然後是從每個工作人員返回到控制器的重用通道(因爲它們是** m ** ultiple ** p ** roducer ,** s ** ingle ** c ** onsumer頻道)。總共應該有N + 1個通道。 – Shepmaster
啊好的。說得通。謝謝。 – codeNoob