WebSocket em Rust: bibliotecas tokio-tungstenite e tungstenite

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Bibliotecas WebSocket para Rust: tungstenite e tokio-tungstenite



WebSocket é um protocolo que fornece comunicação full-duplex entre cliente e servidor sobre uma única conexão TCP. No ecossistema Rust, as bibliotecas mais populares para trabalhar com WebSocket são tungstenite (síncrona) e tokio-tungstenite (assíncrona baseada em Tokio). Ambas as bibliotecas fornecem uma API de alto nível para criar servidores e clientes WebSocket, suportam extensões padrão e segurança via TLS.



Principais funcionalidades

  • tungstenite: implementação síncrona do WebSocket (RFC 6455), suporta operações bloqueantes, adequada para scripts simples e incorporação.
  • tokio-tungstenite: wrapper assíncrono sobre tungstenite, integra-se com o runtime Tokio, permite processar milhares de conexões simultaneamente.
  • Suporte a frames, mensagens, pings/pongs, fechamento de conexão.
  • Trabalho com TLS (através de rustls ou native-tls).
  • Suporte a extensões WebSocket (por exemplo, compressão permessage-deflate).
  • Configuração simples e dependências mínimas.


Instalação

Adicione a biblioteca ao Cargo.toml:

[dependencies]tokio-tungstenite = "0.21"       # variante assíncronatungstenite = "0.21"             # variante síncronatokio = { version = "1", features = ["full"] }  # para tokio-tungstenite


Exemplo de servidor WebSocket assíncrono (tokio-tungstenite)

Vamos criar um simples servidor echo que recebe mensagens de texto e as envia de volta:

use tokio::net::TcpListener;use tokio_tungstenite::accept_async;use tokio_tungstenite::tungstenite::Message;use futures_util::{SinkExt, StreamExt};

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

while let Ok((stream, peer)) = listener.accept().await { tokio::spawn(handle_connection(stream, peer)); } Ok(())}

async fn handle_connection(stream: tokio::net::TcpStream, peer: std::net::SocketAddr) { let ws_stream = match accept_async(stream).await { Ok(ws) => ws, Err(e) => { eprintln!("Erro ao conectar {}: {}", peer, e); return; } };

let (mut write, mut read) = ws_stream.split(); println!("Nova conexão: {}", peer);

while let Some(msg) = read.next().await { match msg { Ok(Message::Text(text)) => { println!("Recebido de {}: {}", peer, text); if let Err(e) = write.send(Message::Text(text.into())).await { eprintln!("Erro ao enviar: {}", e); break; } } Ok(Message::Close(_)) => { println!("Cliente {} desconectado", peer); break; } Err(e) => { eprintln!("Erro: {}", e); break; } _ => {} // Ignoramos mensagens binárias e de controle } }}


Exemplo de cliente WebSocket síncrono (tungstenite)

Um cliente simples que se conecta ao servidor e envia uma mensagem:

use tungstenite::{connect, Message};use url::Url;

fn main() -> Result<(), Box<dyn std::error::Error>> { let url = Url::parse("ws://echo.websocket.org")?; let (mut socket, response) = connect(url)?;

println!("Conectado ao servidor"); println!("Status HTTP: {}", response.status());

socket.send(Message::Text("Olá, WebSocket!".into()))?; println!("Mensagem enviada");

let msg = socket.read()?; if let Message::T

Recommendations