Wynd
A simple, fast, and developer-friendly WebSocket library for Rust.

Features
- 🚀 Simple API: Easy-to-use event-driven API with async/await support
- ⚡ High Performance: Built on Tokio for excellent async performance
- 🛡️ Type Safety: Strongly typed message events and error handling
- 🔧 Developer Experience: Comprehensive documentation and examples
- 🔄 Connection Management: Automatic connection lifecycle management
- 📡 Real-time Ready: Perfect for chat apps, games, and live dashboards
Quick Start
Add Wynd to your Cargo.toml:
[dependencies]
wynd = "0.3"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
Create a simple echo server:
use wynd::wynd::Wynd;
#[tokio::main]
async fn main() {
let mut wynd = Wynd::new();
wynd.on_connection(|conn| async move {
println!("New connection established: {}", conn.id());
conn.on_open(|handle| async move {
println!("Connection {} is now open", handle.id());
let _ = handle.send_text("Welcome to Wynd!").await;
})
.await;
conn.on_text(|msg, handle| async move {
println!("Message received: {}", msg.data);
let _ = handle.send_text(&format!("Echo: {}", msg.data)).await;
});
conn.on_binary(|msg, handle| async move {
println!("Binary message received: {} bytes", msg.data.len());
let _ = handle.send_binary(msg.data).await;
});
conn.on_close(|event| async move {
println!("Connection closed: code={}, reason={}", event.code, event.reason);
});
});
wynd.on_error(|err| async move {
eprintln!("Server error: {}", err);
});
wynd.listen(8080, || {
println!("Server listening on ws://localhost:8080");
})
.await
.unwrap();
}
Examples
Chat Room Server
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::Mutex;
use wynd::wynd::Wynd;
#[tokio::main]
async fn main() {
let mut wynd = Wynd::new();
let clients: Arc<Mutex<HashMap<u64, Arc<wynd::conn::ConnectionHandle>>>> =
Arc::new(Mutex::new(HashMap::new()));
wynd.on_connection(move |conn| {
let value = clients.clone();
async move {
let clients_clone = Arc::clone(&value);
conn.on_open(move |handle| {
let value = clients_clone.clone();
async move {
let clients = Arc::clone(&value);
let handle = Arc::new(handle);
let id = handle.id();
{
let mut clients = clients.lock().await;
clients.insert(id, Arc::clone(&handle));
}
println!("Client {} joined the chat", id);
let _ = handle.send_text("Welcome to the chat room!").await;
broadcast_message(&clients, &format!("Client {} joined", id), id).await;
}
})
.await;
let clients_clone = Arc::clone(&value);
conn.on_text(move |msg, handle| {
let value = clients_clone.clone();
async move {
let clients = Arc::clone(&value);
let id = handle.id();
let message = format!("Client {}: {}", id, msg.data);
broadcast_message(&clients, &message, id).await;
}
});
conn.on_close(|event| async move {
println!(
"Client disconnected: code={}, reason={}",
event.code, event.reason
);
});
}
});
wynd.listen(8080, || {
println!("Chat server listening on ws://localhost:8080");
})
.await
.unwrap();
}
async fn broadcast_message(
clients: &Arc<Mutex<HashMap<u64, Arc<wynd::conn::ConnectionHandle>>>>,
message: &str,
sender_id: u64,
) {
let targets: Vec<Arc<wynd::conn::ConnectionHandle>> = {
let clients = clients.lock().await;
clients
.iter()
.filter(|(id, _)| **id != sender_id)
.map(|(_, handle)| Arc::clone(handle))
.collect()
};
for handle in targets {
let _ = handle.send_text(message).await;
}
}
Documentation
Core Concepts
Wynd Server
The main server instance that manages connections and handles server-level events.
Connection
Represents an individual WebSocket connection with event handlers for different message types.
ConnectionHandle
Provides methods to interact with a connection (send messages, close, etc.).
Events
Typed events for different WebSocket message types:
TextMessageEvent - UTF-8 text messages
BinaryMessageEvent - Binary data
CloseEvent - Connection closure with code and reason
WyndError - Server-level errors
Testing
Test your WebSocket server using any WebSocket client:
Using wscat
npm install -g wscat
wscat -c ws://localhost:8080
Hello, server!
Using a Web Browser
const ws = new WebSocket("ws://localhost:8080");
ws.onopen = function () {
console.log("Connected!");
ws.send("Hello from browser!");
};
ws.onmessage = function (event) {
console.log("Received:", event.data);
};
Performance
Wynd is built for high-performance WebSocket applications:
- Async by Design: Full async/await support with Tokio runtime
- Concurrent Connections: Each connection runs in its own task
- Efficient Message Handling: Minimal overhead for message processing
- Memory Efficient: Smart connection management and cleanup
Error Handling
Wynd provides comprehensive error handling:
match handle.send_text("Hello").await {
Ok(()) => println!("Message sent successfully"),
Err(e) => eprintln!("Failed to send message: {}", e),
}
wynd.on_error(|err| async move {
eprintln!("Server error: {}", err);
});
conn.on_close(|event| async move {
println!("Connection closed: code={}, reason={}", event.code, event.reason);
});
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built on top of Tokio for async runtime
- Uses Tungstenite for WebSocket protocol handling
- Inspired by the need for a simple, developer-friendly WebSocket library in Rust