Bibliotecas WebSocket de Rust: Tokio-tungstenite y async-tungstenite para tiempo real

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Bibliotecas WebSocket de Rust: Tokio-tungstenite y async-tungstenite



En el desarrollo web moderno, el protocolo WebSocket se ha convertido en el estándar para crear aplicaciones en tiempo real: chats, juegos en línea, tickers financieros y sistemas de notificaciones. El ecosistema de Rust ofrece herramientas potentes y seguras para trabajar con WebSocket, entre las que destacan tokio-tungstenite y async-tungstenite. Estas bibliotecas están construidas sobre el popular runtime asíncrono Tokio y la pila WebSocket de alto rendimiento tungstenite.



¿Qué son Tokio-tungstenite y async-tungstenite?



Tokio-tungstenite es una biblioteca WebSocket asíncrona para Rust, integrada con el runtime Tokio. Proporciona abstracciones convenientes para crear servidores y clientes WebSocket, utilizando los tipos estándar de Tokio (TcpListener, TcpStream).



Async-tungstenite es una versión más general que funciona con cualquier runtime asíncrono (Tokio, async-std, smol) a través de los traits AsyncRead y AsyncWrite. Ambas bibliotecas brindan soporte completo para RFC 6455, incluyendo fragmentación de mensajes, ping/pong y enmascaramiento.



Características clave

  • Asincronía — operaciones no bloqueantes usando async/await
  • Alto rendimiento — sobrecarga mínima gracias al análisis zero-copy
  • Seguridad de tipos — los mensajes se representan como estructuras fuertemente tipadas
  • Flexibilidad — soporte tanto para el lado del servidor como del cliente
  • SSL/TLS — soporte integrado para conexiones seguras mediante rustls o native-tls
  • Gestión automática de conexiones — manejo de desconexiones y reconexiones


Instalación

Agregue a Cargo.toml:

[dependencies]tokio = { version = "1", features = ["full"] }tokio-tungstenite = "0.21"futures-util = "0.3"


Ejemplo: Servidor WebSocket

Creemos un servidor echo simple que envía de vuelta el mensaje recibido:

use tokio::net::TcpListener;use tokio_tungstenite::accept_async;use futures_util::{SinkExt, StreamExt};use std::error::Error;

#[tokio::main]async fn main() -> Result<(), Box> { let listener = TcpListener::bind("127.0.0.1:8080").await?; println!("Servidor WebSocket iniciado en ws://127.0.0.1:8080");

while let Ok((stream, addr)) = listener.accept().await { println!("Nueva conexión: {}", addr); tokio::spawn(handle_connection(stream)); } Ok(())}

async fn handle_connection(stream: tokio::net::TcpStream) { let ws_stream = accept_async(stream).await.expect("Error en el handshake"); let (mut write, mut read) = ws_stream.split();

while let Some(Ok(msg)) = read.next().await { if msg.is_text() || msg.is_binary() { // Enviamos el mensaje de vuelta if let Err(e) = write.send(msg).await { eprintln!("Error al enviar: {}", e); break; } } } println!("Conexión cerrada");}


Ejemplo: Cliente WebSocket

Nos conectamos al servidor y enviamos un saludo:

use tokio_tungstenite::connect_async;use futures_util::{SinkExt, StreamExt};use url::Url;

#[tokio::main]async fn main() -> Result<(), Box> { let url = Url::parse("ws://127.0.0.1:8080")?; let (ws_stream, _) = connect_async(url).await?; println!("Conectado al servidor");

let (mut write, mut read) = ws_stream.split();

// Enviamos un mensaje write.send("¡Hola, mundo!".into()).await?; println!("Enviado: ¡Hola, mundo!");

// Leemos la respuesta if let S

Recommendations