¿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”.
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 utilizarunsafe
. Una manera de implementar esto es utilizar un estado compartido entre todas las tareas que manejan las conexiones, comoArc<><><tcpstream>>>
. Esto permite un acceso concurrente seguro al vector de usuarios conectados. Además, el uso deString::from_utf8_lossy
sin comprobar los errores puede llevar a comportamientos inesperados y se debe manejar correctamente en un sistema de producción.