Bibliotecas WebSocket para Rust: tokio-tungstenite e async-tungstenite
WebSocket é um protocolo que fornece comunicação bidirecional entre cliente e servidor através de uma única conexão TCP. No ecossistema Rust, duas bibliotecas principais são usadas para trabalhar com WebSocket: tokio-tungstenite (assíncrona baseada em Tokio) e async-tungstenite (assíncrona, mas com suporte a diferentes runtimes). Ambas são construídas sobre a biblioteca de baixo nível tungstenite, que implementa o próprio protocolo WebSocket.
Por que usar WebSocket em Rust?
Rust é uma linguagem de sistema que é ideal para criar aplicações de rede de alta carga. As bibliotecas WebSocket para Rust permitem:
- Criar chats, jogos, sistemas de notificação em tempo real
- Processar milhares de conexões simultâneas com consumo mínimo de memória
- Usar a segurança de memória do Rust em nível de compilação
- Integrar-se com outras bibliotecas assíncronas (por exemplo, com servidores HTTP)
Instalação e configuração
Adicione a dependência no Cargo.toml:
[dependencies]tokio = { version = "1", features = ["full"] }tokio-tungstenite = "0.21"futures-util = "0.3"Para async-tungstenite:
[dependencies]async-tungstenite = "0.25"async-std = "1.12"Criando um cliente WebSocket em Rust
Exemplo de um cliente simples que se conecta a um servidor e envia uma mensagem:
use futures_util::{SinkExt, StreamExt};use tokio_tungstenite::{connect_async, tungstenite::Message};
#[tokio::main]async fn main() { let url = "wss://echo.websocket.org"; let (mut ws_stream, _) = connect_async(url).await.expect("Erro de conexão");
println!("Conectado ao servidor");
// Envia uma mensagem ws_stream.send(Message::Text("Olá, WebSocket!".into())).await.unwrap();
// Recebe a resposta if let Some(msg) = ws_stream.next().await { let msg = msg.unwrap(); if let Message::Text(text) = msg { println!("Recebido: {}", text); } }
ws_stream.close(None).await.unwrap();}Criando um servidor WebSocket em Rust
Servidor que aceita conexões e responde com eco:
use tokio::net::TcpListener;use tokio_tungstenite::accept_async;use futures_util::{SinkExt, StreamExt};use tokio_tungstenite::tungstenite::Message;
#[tokio::main]async fn main() { let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap(); println!("Servidor iniciado em ws://127.0.0.1:8080");
while let Ok((stream, addr)) = listener.accept().await { tokio::spawn(async move { println!("Nova conexão: {}", addr);
let ws_stream = accept_async(stream).await.unwrap(); let (mut sender, mut receiver) = ws_stream.split();
while let Some(msg) = receiver.next().await { match msg { Ok(Message::Text(text)) => { println!("Mensagem de {}: {}", addr, text); sender.send(Message::Text(format!("Eco: {}", text))).await.unwrap(); } Ok(Message::Close(_)) => break, _ => {} } }
println!("Conexão com {} encerrada", addr); }); }}Principais recursos das bibliotecas
- Suporte a TLS/SSL — conexões seguras via WSS (requer ativação da feature
tls) - Reconexão automática — pode ser implementada com loops e timers
- Frames Ping/Pong — para manter a conexão ativa
- Mensagens binárias — trabalho com
Message::Binary