WebSocket in Rust: Building Real-Time Applications

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to WebSocket in Rust



Real-time applications have become an integral part of the modern web. Chat systems, online games, stock quotes, and real-time notifications all require constant two-way data exchange between client and server. The WebSocket protocol provides exactly this capability, and Rust, thanks to its performance and safety, is an ideal language for building such systems.



In this article, we will thoroughly examine how to create real-time applications in Rust using WebSocket. You will learn about popular crates, architectural approaches, and get ready-made code examples for a quick start.



WebSocket Basics and Library Selection



WebSocket is a protocol that provides full-duplex communication over a single TCP connection. Unlike HTTP, where the client initiates a request and the server responds, WebSocket allows both sides to send data at any time.



Popular Crates for WebSocket in Rust



  • tokio-tungstenite — an asynchronous WebSocket client and server based on Tokio. Lightweight and fast.
  • actix-web — a powerful web framework with built-in WebSocket support.
  • tungstenite — a synchronous version, convenient for simple scenarios.
  • warp — another asynchronous framework with WebSocket support.


For most projects, we recommend tokio-tungstenite or actix-web. The former is for lightweight servers and clients, the latter for full-fledged web applications.



Creating a WebSocket Server in Rust



Let's look at creating a simple echo server that receives messages and sends them back to the client. We'll use tokio-tungstenite.



Project Setup



Create a new Cargo project and add dependencies to Cargo.toml:



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


Basic Echo Server



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

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

while let Ok((stream, addr)) = listener.accept().await { println!("New connection: {}", addr); tokio::spawn(handle_connection(stream)); }

Ok(())}

async fn handle_connection(stream: tokio::net::TcpStream) { let ws_stream = accept_async(stream).await.unwrap(); let (mut write, mut read) = ws_stream.split();

while let Some(msg) = read.next().await { let msg = msg.unwrap(); // Send the message back write.send(msg).await.unwrap(); }}


This code creates a TCP server on port 8080, accepts WebSocket connections, and for each client launches an asynchronous task that echoes all incoming messages.



Creating a WebSocket Client in Rust



Now let's write a client that connects to our server, sends a message, and receives a response.



use futures_util::StreamExt;use tokio_tungstenite::connect_async;

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

println!("Connected to server");

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

// Send a message write.send("Hello, WebSocket!".into()).await?;

// Receive a response if let Some(msg) = read.next().await { let msg = msg?; println!("Received: {}", msg.to_text().unwrap()); }

Ok(())}


Real-time Chat Using actix-web



Now let's

Blogs

Book Recommendations