Actix web ws (actix-ws)
cargo add actix-web actix-ws tokio
use actix_web::{App, HttpRequest, HttpServer, rt, web};
use actix_ws::Message;
async fn ws_handler(request: HttpRequest, body: web::Payload) -> Result<actix_web::HttpResponse, actix_web::error::Error> {
let (response, mut session, mut stream) = actix_ws::handle(&request, body).unwrap();
rt::spawn(async move {
while let Some(message) = stream.recv().await {
match message.unwrap() {
Message::Ping(data) => {
let _ = session.pong(&data).await;
}
Message::Text(message) => {
let _ = session.text(message).await;
}
_ => {
}
}
}
});
Ok(response)
}
#[actix_web::main]
async fn main() {
let _ = HttpServer::new(|| {
App::new()
.route("/ws", web::get().to(ws_handler))
})
.bind("0.0.0.0:3000")
.unwrap()
.run()
.await;
}

tokio-tungstine
use tokio::net::{TcpListener, TcpStream};
use tokio_tungstenite::{accept_async, tungstenite::Message};
use futures_util::{SinkExt, StreamExt};
async fn handle_connection(stream: TcpStream) {
let ws_stream = match accept_async(stream).await {
Ok(ws) => ws,
Err(e) => {
eprintln!("Error during WebSocket handshake: {}", e);
return;
}
};
let (mut write, mut read) = ws_stream.split();
while let Some(message) = read.next().await {
match message {
Ok(Message::Ping(data)) => {
let _ = write.send(Message::Pong(data)).await;
}
Ok(Message::Text(text)) => {
let _ = write.send(Message::Text(text)).await;
}
Ok(Message::Close(_)) => {
break;
}
Err(e) => {
eprintln!("WebSocket error: {}", e);
break;
}
_ => {}
}
}
}
#[tokio::main]
async fn main() {
let listener = TcpListener::bind("0.0.0.0:3000")
.await
.expect("Failed to bind");
println!("WebSocket server listening on 0.0.0.0:3000");
while let Ok((stream, addr)) = listener.accept().await {
println!("New connection from: {}", addr);
tokio::spawn(handle_connection(stream));
}
}