es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Está bien almacenar un vector de clientes globales con “unsafe” al implementar un servidor de chat con async_std?

He implementado un servidor de chat que almacena los usuarios conectados y, si un usuario envía un mensaje, el servidor lo repite a todos los demás clientes.

Tengo experiencia en C++, así que creé una variable global static mut USERS: Vec <TcpStream> para almacenar y acceder a los usuarios.

Manejo los usuarios conectados desde main() de la siguiente manera:

[async_std::main]

async fn main() -> io::Result<()>{
    let listener = TcpListener::bind("127.0.0.1:14530").await?;

loop {
    let (stream, addr) = listener.accept().await?;

    unsafe {
        USERS.push(stream.clone());
    }

    task::spawn(on_connection(stream, addr));
}
}

y la función on_connection es:

async fn on_connection(mut stream: TcpStream, addr: SocketAddr) -> io::Result<()> {
    println!("Nueva conexión: {}", addr.to_string());

let mut buffer = [0u8; 1024];
loop {
    let len = stream.read(&mut buffer).await?; 

    if len > 0 {
        print!("Mensaje de {} => {}", addr.to_string(), String::from_utf8_lossy(&buffer));

        unsafe {
            for mut user in USERS.clone() {
                user.write(&buffer).await?;
            }
        }
    }
    else {
        println!("Desconectado: {}", addr.to_string());

        break
    }
};

Ok(())
}

¿Está bien usar Rust de esta manera?

Quiero hacer que la aplicación sea segura y usar el entorno seguro de Rust sin “unsafe”. Pero no pude descubrir cómo almacenar usuarios globales para acceder más tarde sin “unsafe”.

Tags:  ,

Answer

  1. Avatar for davy.ai

    No, está mal utilizar Rust de esta manera. El uso de unsafe se desaconseja en Rust y generalmente solo se utiliza al interactuar con código de bajo nivel o cuando no existe otra forma de lograr la funcionalidad requerida. En este caso, existen formas más seguras de almacenar a los usuarios conectados sin utilizar unsafe. Una manera de implementar esto es utilizar un estado compartido entre todas las tareas que manejan las conexiones, como Arc<><><tcpstream>>>. Esto permite un acceso concurrente seguro al vector de usuarios conectados. Además, el uso de String::from_utf8_lossy sin comprobar los errores puede llevar a comportamientos inesperados y se debe manejar correctamente en un sistema de producción.

Comments are closed.