WebSocket библиотеки Rust: Tokio-tungstenite и async-tungstenite для реального времени

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

WebSocket библиотеки Rust: Tokio-tungstenite и async-tungstenite

В современной веб-разработке протокол WebSocket стал стандартом для создания приложений реального времени: чатов, онлайн-игр, финансовых тикеров и систем уведомлений. Экосистема Rust предлагает мощные и безопасные инструменты для работы с WebSocket, среди которых выделяются tokio-tungstenite и async-tungstenite. Эти библиотеки построены на базе популярного асинхронного рантайма Tokio и высокопроизводительного WebSocket-стека tungstenite.

Что такое Tokio-tungstenite и async-tungstenite?

Tokio-tungstenite — это асинхронная WebSocket библиотека для Rust, интегрированная с рантаймом Tokio. Она предоставляет удобные абстракции для создания WebSocket серверов и клиентов, используя стандартные типы Tokio (TcpListener, TcpStream).

Async-tungstenite — это более общая версия, которая работает с любым асинхронным рантаймом (Tokio, async-std, smol) через трейты AsyncRead и AsyncWrite. Обе библиотеки обеспечивают полную поддержку RFC 6455, включая фрагментацию сообщений, ping/pong и маскирование.

Ключевые возможности

  • Асинхронность — неблокирующие операции с использованием async/await
  • Высокая производительность — минимальные накладные расходы благодаря zero-copy парсингу
  • Типобезопасность — сообщения представлены как строго типизированные структуры
  • Гибкость — поддержка как серверной, так и клиентской сторон
  • SSL/TLS — встроенная поддержка защищенных соединений через rustls или native-tls
  • Автоматическое управление соединениями — обработка разрывов и переподключений

Установка

Добавьте в Cargo.toml:

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

Пример: WebSocket сервер

Создадим простой echo-сервер, который отправляет обратно полученное сообщение:

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!("WebSocket сервер запущен на ws://127.0.0.1:8080");

    while let Ok((stream, addr)) = listener.accept().await {
        println!("Новое подключение: {}", addr);
        tokio::spawn(handle_connection(stream));
    }
    Ok(())
}

async fn handle_connection(stream: tokio::net::TcpStream) {
    let ws_stream = accept_async(stream).await.expect("Ошибка handshake");
    let (mut write, mut read) = ws_stream.split();

    while let Some(Ok(msg)) = read.next().await {
        if msg.is_text() || msg.is_binary() {
            // Отправляем сообщение обратно
            if let Err(e) = write.send(msg).await {
                eprintln!("Ошибка отправки: {}", e);
                break;
            }
        }
    }
    println!("Соединение закрыто");
}

Пример: WebSocket клиент

Подключаемся к серверу и отправляем приветствие:

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!("Подключено к серверу");

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

    // Отправляем сообщение
    write.send("Привет, мир!".into()).await?;
    println!("Отправлено: Привет, мир!");

    // Читаем ответ
    if let Some(Ok(msg)) = read.next().await {
        println!("Получено: {}", msg.to_text().unwrap());
    }

    Ok(())
}

Продвинутые возможности

Библиотека поддерживает:

  • SSL/TLS — используйте connect_async_tls_with_config для защищенных соединений
  • Кастомные заголовки — передача дополнительных HTTP-заголовков при hand

Рекомендаций