rust - отправляет данные из аргумента функции (из потока) в канал mpsc - PullRequest
0 голосов
/ 27 октября 2019

Я пытаюсь обработать TcpStream, используя потоки в программе Rust (tcp-сервер). Я хочу отслеживать текущие соединения клиентов в HashMap, используя Arc<Mutex<HashMap>>.

Когда поток завершен, чтобы удалить соединение из HashMap, я подумал об использовании uuid, переданногок функции, используемой для обработки потока. Таким образом, его можно отправить внутри канала mpsc в основной поток, а затем удалить соединение из HashMap.

Код из основного потока:

let clients_streams = Arc::new(Mutex::new(HashMap::new()));

// Server thread. Create channel
let (server_sender, server_receiver) = mpsc::channel();

loop {
    for stream in server_socket.incoming() {
        let clients_streams = Arc::clone(&clients_streams);
        let server_sender = server_sender.clone();
        let mut cs = clients_streams.lock().unwrap();

        match stream {
            Ok(stream) => {
                let mut cs = clients_streams.lock().unwrap();
                let uuid = Uuid::new_v4().to_string();
                cs.insert(uuid.clone(), stream.try_clone());

                thread::spawn(move || {
                    handle_client(stream, server_sender.clone(), uuid.clone());
                })
            }
            Err(err) => thread::spawn(move || {
                println!("Connection failed : {}", err);
            }),
        };
    }

Функция handle_client:

fn handle_client<'a>(stream: TcpStream, sender: mpsc::Sender<&'a [u8]>, uuid: String) {
    let mut reader = BufReader::new(&stream);
    let mut writer = BufWriter::new(&stream);

    writer.write(b"Hello\n").unwrap();
    writer.flush().unwrap();

    // Read from client
    loop {
        let mut resp = Vec::new();
        let read_bytes = reader.read_until(b'\n', &mut resp);
        match read_bytes {
            Ok(read_bytes) => {
                if read_bytes == 0 {
                    let msg = format!("end of {}", uuid);
                    println!("connection closed by remote");
                    sender.send(msg.as_bytes()).unwrap();
                    break;
                };
            }
            Err(err) => match err.kind() {
                io::ErrorKind::Interrupted => continue,
                _ => break,
            },
        }
    }
}

Этот код не компилируется, он показывает эту ошибку, но яне понимаю, как решить это. Переменная msg не живет достаточно долго из-за uuid внутри нее, но почему? Мне пришлось добавить время жизни, потому что я посылаю uuid внутри канала.

 fn handle_client<'a>(stream: TcpStream, sender: mpsc::Sender<&'a [u8]>, uuid: String) {
             -- lifetime `'a` defined here

                sender.send(msg.as_bytes()).unwrap();
                ------------^^^------------
                |           |
                |           borrowed value does not live long enough
                argument requires that `msg` is borrowed for `'a`
                break;
            };
            - `msg` dropped here while still borrowed

1 Ответ

0 голосов
/ 27 октября 2019

Uuid не влияет на msg, потому что макрос формата создает новую чистую строку. Вы пытаетесь отправить & [u8] (это то, что возвращает as_bytes ()). Вам нужно найти способ удалить эту ссылку. (может быть это что-то вроде Как конвертировать из & [u8] в Vec? ) Вы также можете поделиться ссылками с Rc.

PS: это скорее комментарий, чем ответ, но я не могу публиковать ответы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...