¡Bienvenidos de nuevo a Rustaceo.es! Hoy construiremos un servidor de chat asíncrono en Rust, utilizando tokio
para manejar múltiples conexiones sin bloquear el sistema. Aprenderemos a enviar y recibir mensajes en tiempo real, asegurando una comunicación eficiente entre clientes.
🚀 Objetivos del proyecto #
- Manejar múltiples clientes concurrentemente usando Tokio.
- Implementar comunicación bidireccional con
tokio::sync::broadcast
. - Crear un servidor TCP asíncrono para gestionar clientes en tiempo real.
⚡ Configuración del proyecto #
Primero, inicializamos un nuevo proyecto con Tokio:
cargo new async-chat-server --bin
cd async-chat-server
Luego, agregamos Tokio en Cargo.toml
:
[dependencies]
tokio = { version = "1", features = ["full"] }
🏗 Implementando el servidor de chat #
📌 Configuración del servidor tcp #
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::broadcast;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use std::sync::Arc;
#[Tokio::main]
async fn main() {
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
let (tx, _rx) = broadcast::channel(10);
println!("Servidor de chat iniciado en 127.0.0.1:8080");
loop {
let (socket, _) = listener.accept().await.unwrap();
let tx = tx.clone();
let rx = tx.subscribe();
tokio::spawn(async move {
manejar_cliente(socket, tx, rx).await;
});
}
}
🔹 TcpListener::bind
: Inicia un servidor TCP en el puerto 8080. 🔹 broadcast::channel(10)
: Canal de transmisión para enviar mensajes a múltiples clientes. 🔹 tokio::spawn
: Lanza cada cliente en una tarea separada para manejar múltiples conexiones simultáneamente.
📬 Manejo de clientes y mensajes #
async fn manejar_cliente(socket: TcpStream, tx: broadcast::Sender<String>, mut rx: broadcast::Receiver<String>) {
let mut reader = BufReader::new(socket);
let mut line = String::new();
let (mut reader, mut writer) = reader.split();
tokio::spawn(async move {
while let Ok(msg) = rx.recv().await {
writer.write_all(msg.as_bytes()).await.unwrap();
}
});
while reader.read_line(&mut line).await.unwrap() > 0 {
let mensaje = line.trim().to_string();
tx.send(mensaje.clone()).unwrap();
line.clear();
}
}
🔹 rx.recv().await
: Recibe mensajes de otros clientes y los envía al cliente actual. 🔹 reader.read_line().await
: Espera mensajes del cliente y los retransmite a todos. 🔹 tx.send()
: Envía el mensaje a todos los suscriptores del canal.
🏆 Probando el servidor de chat #
Para probar el servidor, ejecutamos:
cargo run
Luego, podemos conectarnos con nc
en múltiples terminales:
nc 127.0.0.1 8080
Cada mensaje enviado se retransmitirá a todos los clientes conectados.
📌 Conclusión #
Hemos construido un servidor de chat asíncrono en Rust que permite múltiples clientes simultáneos sin bloquear el sistema.
✔ Tokio para concurrencia eficiente ✔ Mensajería con broadcast
para comunicación en tiempo real ✔ Manejo seguro de múltiples clientes en un entorno asíncrono
🔮 Próximo paso: Implementar autenticación y cifrado en la comunicación.
¡Nos vemos en la siguiente entrega, Rustaceos!