🦀 Networking Patterns in TuskLang with Rust
Networking Patterns in TuskLang with Rust
🌐 Networking Foundation
Networking patterns with TuskLang and Rust provide powerful tools for building high-performance network applications. This guide covers TCP/UDP, HTTP clients/servers, WebSocket, and advanced networking techniques.
🏗️ Networking Architecture
Network Stack
[network_architecture]
tcp_udp: true
http_servers: true
websocket: true
grpc: true[network_components]
tokio: "async_runtime"
hyper: "http_framework"
warp: "web_framework"
tonic: "grpc_framework"
Network Configuration
[network_configuration]
connection_pooling: true
load_balancing: true
rate_limiting: true
ssl_tls: true[network_implementation]
use tokio::net::{TcpListener, TcpStream};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use std::collections::HashMap;
use tokio::sync::RwLock;
// Network manager
pub struct NetworkManager {
config: NetworkConfig,
connections: Arc<RwLock<HashMap<String, ConnectionInfo>>>,
metrics: Arc<RwLock<NetworkMetrics>>,
}
#[derive(Debug, Clone)]
pub struct NetworkConfig {
pub max_connections: usize,
pub connection_timeout: Duration,
pub read_timeout: Duration,
pub write_timeout: Duration,
pub enable_ssl: bool,
pub enable_compression: bool,
}
#[derive(Debug, Clone)]
pub struct ConnectionInfo {
pub id: String,
pub remote_addr: String,
pub local_addr: String,
pub protocol: Protocol,
pub established_at: Instant,
pub last_activity: Instant,
pub bytes_sent: u64,
pub bytes_received: u64,
}
#[derive(Debug, Clone)]
pub enum Protocol {
TCP,
UDP,
HTTP,
WebSocket,
GRPC,
}
#[derive(Debug, Clone)]
pub struct NetworkMetrics {
pub total_connections: u64,
pub active_connections: u64,
pub total_bytes_sent: u64,
pub total_bytes_received: u64,
pub connection_errors: u64,
pub timeout_errors: u64,
}
impl NetworkManager {
pub fn new(config: NetworkConfig) -> Self {
Self {
config,
connections: Arc::new(RwLock::new(HashMap::new())),
metrics: Arc::new(RwLock::new(NetworkMetrics {
total_connections: 0,
active_connections: 0,
total_bytes_sent: 0,
total_bytes_received: 0,
connection_errors: 0,
timeout_errors: 0,
})),
}
}
pub async fn create_connection(&self, addr: &str, protocol: Protocol) -> Result<Connection, NetworkError> {
let connection_id = uuid::Uuid::new_v4().to_string();
let connection = match protocol {
Protocol::TCP => {
let stream = TcpStream::connect(addr).await
.map_err(|e| NetworkError::ConnectionFailed { message: e.to_string() })?;
Connection::Tcp(stream)
}
Protocol::UDP => {
let socket = tokio::net::UdpSocket::bind("0.0.0.0:0").await
.map_err(|e| NetworkError::ConnectionFailed { message: e.to_string() })?;
socket.connect(addr).await
.map_err(|e| NetworkError::ConnectionFailed { message: e.to_string() })?;
Connection::Udp(socket)
}
_ => return Err(NetworkError::UnsupportedProtocol { protocol: format!("{:?}", protocol) }),
};
let connection_info = ConnectionInfo {
id: connection_id.clone(),
remote_addr: addr.to_string(),
local_addr: "0.0.0.0:0".to_string(),
protocol,
established_at: Instant::now(),
last_activity: Instant::now(),
bytes_sent: 0,
bytes_received: 0,
};
{
let mut connections = self.connections.write().await;
connections.insert(connection_id.clone(), connection_info);
}
{
let mut metrics = self.metrics.write().await;
metrics.total_connections += 1;
metrics.active_connections += 1;
}
Ok(connection)
}
pub async fn get_metrics(&self) -> NetworkMetrics {
self.metrics.read().await.clone()
}
pub async fn get_connection_info(&self, connection_id: &str) -> Option<ConnectionInfo> {
self.connections.read().await.get(connection_id).cloned()
}
}
#[derive(Debug, thiserror::Error)]
pub enum NetworkError {
#[error("Connection failed: {message}")]
ConnectionFailed { message: String },
#[error("Unsupported protocol: {protocol}")]
UnsupportedProtocol { protocol: String },
#[error("Timeout error: {message}")]
Timeout { message: String },
#[error("IO error: {message}")]
Io { message: String },
}
pub enum Connection {
Tcp(TcpStream),
Udp(tokio::net::UdpSocket),
}
🔌 TCP/UDP Patterns
TCP Server
[tcp_udp_patterns]
tcp_server: true
tcp_client: true
udp_server: true
udp_client: true[tcp_implementation]
use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
// TCP Server
pub struct TcpServer {
listener: TcpListener,
config: ServerConfig,
handlers: Arc<RwLock<HashMap<String, Box<dyn MessageHandler + Send + Sync>>>>,
}
#[derive(Debug, Clone)]
pub struct ServerConfig {
pub host: String,
pub port: u16,
pub max_connections: usize,
pub buffer_size: usize,
pub enable_keepalive: bool,
}
pub trait MessageHandler {
fn handle_message(&self, message: &[u8]) -> Result<Vec<u8>, String>;
fn get_handler_name(&self) -> &str;
}
impl TcpServer {
pub async fn new(config: ServerConfig) -> Result<Self, std::io::Error> {
let addr = format!("{}:{}", config.host, config.port);
let listener = TcpListener::bind(&addr).await?;
println!("TCP Server listening on {}", addr);
Ok(Self {
listener,
config,
handlers: Arc::new(RwLock::new(HashMap::new())),
})
}
pub async fn register_handler(&self, name: String, handler: Box<dyn MessageHandler + Send + Sync>) {
let mut handlers = self.handlers.write().await;
handlers.insert(name, handler);
}
pub async fn start(&self) -> Result<(), std::io::Error> {
let mut connection_count = 0;
loop {
if connection_count >= self.config.max_connections {
tokio::time::sleep(Duration::from_millis(100)).await;
continue;
}
match self.listener.accept().await {
Ok((socket, addr)) => {
connection_count += 1;
println!("New connection from: {}", addr);
let handlers = Arc::clone(&self.handlers);
let config = self.config.clone();
tokio::spawn(async move {
Self::handle_connection(socket, addr, handlers, config).await;
connection_count -= 1;
});
}
Err(e) => {
eprintln!("Error accepting connection: {}", e);
}
}
}
}
async fn handle_connection(
mut socket: TcpStream,
addr: std::net::SocketAddr,
handlers: Arc<RwLock<HashMap<String, Box<dyn MessageHandler + Send + Sync>>>>,
config: ServerConfig,
) {
let mut buffer = vec![0u8; config.buffer_size];
loop {
match socket.read(&mut buffer).await {
Ok(0) => {
println!("Connection closed by client: {}", addr);
break;
}
Ok(n) => {
let message = &buffer[..n];
// Parse message to determine handler
if let Some(handler_name) = Self::extract_handler_name(message) {
let handlers = handlers.read().await;
if let Some(handler) = handlers.get(handler_name) {
match handler.handle_message(message) {
Ok(response) => {
if let Err(e) = socket.write_all(&response).await {
eprintln!("Error writing response: {}", e);
break;
}
}
Err(e) => {
eprintln!("Handler error: {}", e);
let error_response = format!("Error: {}", e).into_bytes();
if let Err(e) = socket.write_all(&error_response).await {
eprintln!("Error writing error response: {}", e);
break;
}
}
}
} else {
let error_response = format!("Unknown handler: {}", handler_name).into_bytes();
if let Err(e) = socket.write_all(&error_response).await {
eprintln!("Error writing error response: {}", e);
break;
}
}
} else {
let error_response = b"Invalid message format".to_vec();
if let Err(e) = socket.write_all(&error_response).await {
eprintln!("Error writing error response: {}", e);
break;
}
}
}
Err(e) => {
eprintln!("Error reading from socket: {}", e);
break;
}
}
}
}
fn extract_handler_name(message: &[u8]) -> Option<&str> {
// Simple protocol: first line contains handler name
if let Ok(message_str) = std::str::from_utf8(message) {
message_str.lines().next()
} else {
None
}
}
}
// TCP Client
pub struct TcpClient {
config: ClientConfig,
connection_pool: Arc<RwLock<Vec<TcpStream>>>,
}
#[derive(Debug, Clone)]
pub struct ClientConfig {
pub server_host: String,
pub server_port: u16,
pub connection_timeout: Duration,
pub max_connections: usize,
pub enable_keepalive: bool,
}
impl TcpClient {
pub fn new(config: ClientConfig) -> Self {
Self {
config,
connection_pool: Arc::new(RwLock::new(Vec::new())),
}
}
pub async fn connect(&self) -> Result<TcpStream, std::io::Error> {
let addr = format!("{}:{}", self.config.server_host, self.config.server_port);
let stream = tokio::time::timeout(
self.config.connection_timeout,
TcpStream::connect(&addr)
).await
.map_err(|_| std::io::Error::new(std::io::ErrorKind::TimedOut, "Connection timeout"))??;
Ok(stream)
}
pub async fn send_message(&self, message: &[u8]) -> Result<Vec<u8>, NetworkError> {
let mut stream = self.connect().await
.map_err(|e| NetworkError::ConnectionFailed { message: e.to_string() })?;
// Send message
stream.write_all(message).await
.map_err(|e| NetworkError::Io { message: e.to_string() })?;
// Read response
let mut buffer = vec![0u8; 1024];
let n = stream.read(&mut buffer).await
.map_err(|e| NetworkError::Io { message: e.to_string() })?;
Ok(buffer[..n].to_vec())
}
pub async fn send_message_with_handler(&self, handler_name: &str, data: &[u8]) -> Result<Vec<u8>, NetworkError> {
let message = format!("{}\n{}", handler_name, String::from_utf8_lossy(data));
self.send_message(message.as_bytes()).await
}
}
UDP Server
[udp_implementation]
use tokio::net::UdpSocket;// UDP Server
pub struct UdpServer {
socket: UdpSocket,
config: ServerConfig,
handlers: Arc<RwLock<HashMap<String, Box<dyn MessageHandler + Send + Sync>>>>,
}
impl UdpServer {
pub async fn new(config: ServerConfig) -> Result<Self, std::io::Error> {
let addr = format!("{}:{}", config.host, config.port);
let socket = UdpSocket::bind(&addr).await?;
println!("UDP Server listening on {}", addr);
Ok(Self {
socket,
config,
handlers: Arc::new(RwLock::new(HashMap::new())),
})
}
pub async fn register_handler(&self, name: String, handler: Box<dyn MessageHandler + Send + Sync>) {
let mut handlers = self.handlers.write().await;
handlers.insert(name, handler);
}
pub async fn start(&self) -> Result<(), std::io::Error> {
let mut buffer = vec![0u8; self.config.buffer_size];
loop {
match self.socket.recv_from(&mut buffer).await {
Ok((n, addr)) => {
let message = &buffer[..n];
println!("Received {} bytes from {}", n, addr);
let handlers = Arc::clone(&self.handlers);
let socket = self.socket.try_clone().await?;
tokio::spawn(async move {
Self::handle_message(socket, addr, message, handlers).await;
});
}
Err(e) => {
eprintln!("Error receiving from socket: {}", e);
}
}
}
}
async fn handle_message(
socket: UdpSocket,
addr: std::net::SocketAddr,
message: &[u8],
handlers: Arc<RwLock<HashMap<String, Box<dyn MessageHandler + Send + Sync>>>>,
) {
if let Some(handler_name) = Self::extract_handler_name(message) {
let handlers = handlers.read().await;
if let Some(handler) = handlers.get(handler_name) {
match handler.handle_message(message) {
Ok(response) => {
if let Err(e) = socket.send_to(&response, addr).await {
eprintln!("Error sending response: {}", e);
}
}
Err(e) => {
eprintln!("Handler error: {}", e);
let error_response = format!("Error: {}", e).into_bytes();
if let Err(e) = socket.send_to(&error_response, addr).await {
eprintln!("Error sending error response: {}", e);
}
}
}
} else {
let error_response = format!("Unknown handler: {}", handler_name).into_bytes();
if let Err(e) = socket.send_to(&error_response, addr).await {
eprintln!("Error sending error response: {}", e);
}
}
} else {
let error_response = b"Invalid message format".to_vec();
if let Err(e) = socket.send_to(&error_response, addr).await {
eprintln!("Error sending error response: {}", e);
}
}
}
fn extract_handler_name(message: &[u8]) -> Option<&str> {
if let Ok(message_str) = std::str::from_utf8(message) {
message_str.lines().next()
} else {
None
}
}
}
🌐 HTTP Patterns
HTTP Server
[http_patterns]
http_server: true
http_client: true
middleware: true
routing: true[http_implementation]
use hyper::{
service::{make_service_fn, service_fn},
Body, Request, Response, Server,
http::{Method, StatusCode, Uri},
};
use std::convert::Infallible;
use std::sync::Arc;
// HTTP Server
pub struct HttpServer {
config: HttpServerConfig,
routes: Arc<RwLock<HashMap<String, Box<dyn HttpHandler + Send + Sync>>>>,
middleware: Arc<RwLock<Vec<Box<dyn Middleware + Send + Sync>>>>,
}
#[derive(Debug, Clone)]
pub struct HttpServerConfig {
pub host: String,
pub port: u16,
pub max_connections: usize,
pub enable_cors: bool,
pub enable_compression: bool,
}
pub trait HttpHandler {
fn handle(&self, req: Request<Body>) -> Result<Response<Body>, hyper::Error>;
fn get_path(&self) -> &str;
fn get_method(&self) -> Method;
}
pub trait Middleware {
fn process(&self, req: Request<Body>) -> Result<Request<Body>, hyper::Error>;
fn process_response(&self, res: Response<Body>) -> Result<Response<Body>, hyper::Error>;
}
impl HttpServer {
pub fn new(config: HttpServerConfig) -> Self {
Self {
config,
routes: Arc::new(RwLock::new(HashMap::new())),
middleware: Arc::new(RwLock::new(Vec::new())),
}
}
pub async fn register_handler(&self, handler: Box<dyn HttpHandler + Send + Sync>) {
let key = format!("{}:{}", handler.get_method(), handler.get_path());
let mut routes = self.routes.write().await;
routes.insert(key, handler);
}
pub async fn register_middleware(&self, middleware: Box<dyn Middleware + Send + Sync>) {
let mut middleware_list = self.middleware.write().await;
middleware_list.push(middleware);
}
pub async fn start(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr = format!("{}:{}", self.config.host, self.config.port)
.parse()?;
let routes = Arc::clone(&self.routes);
let middleware = Arc::clone(&self.middleware);
let config = self.config.clone();
let make_svc = make_service_fn(move |_conn| {
let routes = Arc::clone(&routes);
let middleware = Arc::clone(&middleware);
let config = config.clone();
async move {
Ok::<_, Infallible>(service_fn(move |req| {
let routes = Arc::clone(&routes);
let middleware = Arc::clone(&middleware);
let config = config.clone();
async move {
Self::handle_request(req, routes, middleware, config).await
}
}))
}
});
let server = Server::bind(&addr).serve(make_svc);
println!("HTTP Server listening on {}", addr);
server.await?;
Ok(())
}
async fn handle_request(
req: Request<Body>,
routes: Arc<RwLock<HashMap<String, Box<dyn HttpHandler + Send + Sync>>>>,
middleware: Arc<RwLock<Vec<Box<dyn Middleware + Send + Sync>>>>,
config: HttpServerConfig,
) -> Result<Response<Body>, hyper::Error> {
let method = req.method().clone();
let uri = req.uri().clone();
let path = uri.path();
// Apply middleware
let mut processed_req = req;
{
let middleware_list = middleware.read().await;
for mw in middleware_list.iter() {
processed_req = mw.process(processed_req)?;
}
}
// Find handler
let key = format!("{}:{}", method, path);
let routes = routes.read().await;
if let Some(handler) = routes.get(&key) {
let mut response = handler.handle(processed_req)?;
// Apply response middleware
{
let middleware_list = middleware.read().await;
for mw in middleware_list.iter() {
response = mw.process_response(response)?;
}
}
// Add CORS headers if enabled
if config.enable_cors {
response.headers_mut().insert(
"Access-Control-Allow-Origin",
"*".parse().unwrap()
);
response.headers_mut().insert(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS".parse().unwrap()
);
response.headers_mut().insert(
"Access-Control-Allow-Headers",
"Content-Type, Authorization".parse().unwrap()
);
}
Ok(response)
} else {
// 404 Not Found
let mut response = Response::new(Body::from("Not Found"));
*response.status_mut() = StatusCode::NOT_FOUND;
Ok(response)
}
}
}
// Example HTTP handlers
pub struct HealthCheckHandler;
impl HttpHandler for HealthCheckHandler {
fn handle(&self, _req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
let response = Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "application/json")
.body(Body::from(r#"{"status":"healthy"}"#))
.unwrap();
Ok(response)
}
fn get_path(&self) -> &str {
"/health"
}
fn get_method(&self) -> Method {
Method::GET
}
}
pub struct ApiHandler;
impl HttpHandler for ApiHandler {
fn handle(&self, req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
let response = Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "application/json")
.body(Body::from(r#"{"message":"API endpoint"}"#))
.unwrap();
Ok(response)
}
fn get_path(&self) -> &str {
"/api"
}
fn get_method(&self) -> Method {
Method::GET
}
}
HTTP Client
[http_client_implementation]
use hyper::{Client, Body, Request, Response};
use hyper_tls::HttpsConnector;
use std::collections::HashMap;// HTTP Client
pub struct HttpClient {
client: Client<HttpsConnector<hyper::client::HttpConnector>>,
config: HttpClientConfig,
headers: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct HttpClientConfig {
pub timeout: Duration,
pub max_retries: usize,
pub enable_compression: bool,
pub user_agent: String,
}
impl HttpClient {
pub fn new(config: HttpClientConfig) -> Self {
let https = HttpsConnector::new();
let client = Client::builder().build::<_, Body>(https);
let mut headers = HashMap::new();
headers.insert("User-Agent".to_string(), config.user_agent.clone());
Self {
client,
config,
headers,
}
}
pub fn add_header(&mut self, key: String, value: String) {
self.headers.insert(key, value);
}
pub async fn get(&self, url: &str) -> Result<Response<Body>, hyper::Error> {
let mut req = Request::builder()
.method(Method::GET)
.uri(url);
for (key, value) in &self.headers {
req = req.header(key, value);
}
let req = req.body(Body::empty())?;
self.client.request(req).await
}
pub async fn post(&self, url: &str, body: Vec<u8>) -> Result<Response<Body>, hyper::Error> {
let mut req = Request::builder()
.method(Method::POST)
.uri(url)
.header("Content-Type", "application/json");
for (key, value) in &self.headers {
req = req.header(key, value);
}
let req = req.body(Body::from(body))?;
self.client.request(req).await
}
pub async fn put(&self, url: &str, body: Vec<u8>) -> Result<Response<Body>, hyper::Error> {
let mut req = Request::builder()
.method(Method::PUT)
.uri(url)
.header("Content-Type", "application/json");
for (key, value) in &self.headers {
req = req.header(key, value);
}
let req = req.body(Body::from(body))?;
self.client.request(req).await
}
pub async fn delete(&self, url: &str) -> Result<Response<Body>, hyper::Error> {
let mut req = Request::builder()
.method(Method::DELETE)
.uri(url);
for (key, value) in &self.headers {
req = req.header(key, value);
}
let req = req.body(Body::empty())?;
self.client.request(req).await
}
}
🔌 WebSocket Patterns
WebSocket Server
[websocket_patterns]
websocket_server: true
websocket_client: true
real_time: true[websocket_implementation]
use tokio_tungstenite::{accept_async, WebSocketStream};
use futures::{SinkExt, StreamExt};
use tokio::net::TcpListener;
// WebSocket Server
pub struct WebSocketServer {
listener: TcpListener,
config: WebSocketConfig,
handlers: Arc<RwLock<HashMap<String, Box<dyn WebSocketHandler + Send + Sync>>>>,
connections: Arc<RwLock<HashMap<String, WebSocketConnection>>>,
}
#[derive(Debug, Clone)]
pub struct WebSocketConfig {
pub host: String,
pub port: u16,
pub max_connections: usize,
pub enable_compression: bool,
pub ping_interval: Duration,
}
pub trait WebSocketHandler {
fn handle_message(&self, message: String, connection_id: &str) -> Result<String, String>;
fn handle_connect(&self, connection_id: &str) -> Result<(), String>;
fn handle_disconnect(&self, connection_id: &str) -> Result<(), String>;
fn get_handler_name(&self) -> &str;
}
#[derive(Debug)]
pub struct WebSocketConnection {
pub id: String,
pub remote_addr: String,
pub connected_at: Instant,
pub last_activity: Instant,
pub message_count: u64,
}
impl WebSocketServer {
pub async fn new(config: WebSocketConfig) -> Result<Self, std::io::Error> {
let addr = format!("{}:{}", config.host, config.port);
let listener = TcpListener::bind(&addr).await?;
println!("WebSocket Server listening on {}", addr);
Ok(Self {
listener,
config,
handlers: Arc::new(RwLock::new(HashMap::new())),
connections: Arc::new(RwLock::new(HashMap::new())),
})
}
pub async fn register_handler(&self, handler: Box<dyn WebSocketHandler + Send + Sync>) {
let mut handlers = self.handlers.write().await;
handlers.insert(handler.get_handler_name().to_string(), handler);
}
pub async fn start(&self) -> Result<(), std::io::Error> {
let mut connection_count = 0;
loop {
if connection_count >= self.config.max_connections {
tokio::time::sleep(Duration::from_millis(100)).await;
continue;
}
match self.listener.accept().await {
Ok((socket, addr)) => {
connection_count += 1;
println!("New WebSocket connection from: {}", addr);
let handlers = Arc::clone(&self.handlers);
let connections = Arc::clone(&self.connections);
let config = self.config.clone();
tokio::spawn(async move {
Self::handle_connection(socket, addr, handlers, connections, config).await;
connection_count -= 1;
});
}
Err(e) => {
eprintln!("Error accepting WebSocket connection: {}", e);
}
}
}
}
async fn handle_connection(
socket: TcpStream,
addr: std::net::SocketAddr,
handlers: Arc<RwLock<HashMap<String, Box<dyn WebSocketHandler + Send + Sync>>>>,
connections: Arc<RwLock<HashMap<String, WebSocketConnection>>>,
config: WebSocketConfig,
) {
let ws_stream = match accept_async(socket).await {
Ok(ws) => ws,
Err(e) => {
eprintln!("Error accepting WebSocket: {}", e);
return;
}
};
let connection_id = uuid::Uuid::new_v4().to_string();
// Register connection
{
let mut conns = connections.write().await;
conns.insert(connection_id.clone(), WebSocketConnection {
id: connection_id.clone(),
remote_addr: addr.to_string(),
connected_at: Instant::now(),
last_activity: Instant::now(),
message_count: 0,
});
}
// Notify handlers of new connection
{
let handlers = handlers.read().await;
for handler in handlers.values() {
if let Err(e) = handler.handle_connect(&connection_id) {
eprintln!("Handler connect error: {}", e);
}
}
}
let (mut ws_sender, mut ws_receiver) = ws_stream.split();
// Handle incoming messages
while let Some(msg) = ws_receiver.next().await {
match msg {
Ok(msg) => {
if let tokio_tungstenite::tungstenite::Message::Text(text) = msg {
// Update last activity
{
let mut conns = connections.write().await;
if let Some(conn) = conns.get_mut(&connection_id) {
conn.last_activity = Instant::now();
conn.message_count += 1;
}
}
// Parse message to determine handler
if let Some((handler_name, message)) = Self::parse_message(&text) {
let handlers = handlers.read().await;
if let Some(handler) = handlers.get(&handler_name) {
match handler.handle_message(message, &connection_id) {
Ok(response) => {
let response_msg = tokio_tungstenite::tungstenite::Message::Text(response);
if let Err(e) = ws_sender.send(response_msg).await {
eprintln!("Error sending WebSocket response: {}", e);
break;
}
}
Err(e) => {
eprintln!("Handler error: {}", e);
let error_response = tokio_tungstenite::tungstenite::Message::Text(
format!("Error: {}", e)
);
if let Err(e) = ws_sender.send(error_response).await {
eprintln!("Error sending WebSocket error response: {}", e);
break;
}
}
}
} else {
let error_response = tokio_tungstenite::tungstenite::Message::Text(
format!("Unknown handler: {}", handler_name)
);
if let Err(e) = ws_sender.send(error_response).await {
eprintln!("Error sending WebSocket error response: {}", e);
break;
}
}
} else {
let error_response = tokio_tungstenite::tungstenite::Message::Text(
"Invalid message format".to_string()
);
if let Err(e) = ws_sender.send(error_response).await {
eprintln!("Error sending WebSocket error response: {}", e);
break;
}
}
}
}
Err(e) => {
eprintln!("WebSocket error: {}", e);
break;
}
}
}
// Notify handlers of disconnection
{
let handlers = handlers.read().await;
for handler in handlers.values() {
if let Err(e) = handler.handle_disconnect(&connection_id) {
eprintln!("Handler disconnect error: {}", e);
}
}
}
// Remove connection
{
let mut conns = connections.write().await;
conns.remove(&connection_id);
}
println!("WebSocket connection closed: {}", addr);
}
fn parse_message(text: &str) -> Option<(String, String)> {
if let Some(pos) = text.find(':') {
let handler_name = text[..pos].trim().to_string();
let message = text[pos + 1..].trim().to_string();
Some((handler_name, message))
} else {
None
}
}
}
🎯 Best Practices
1. Connection Management
- Implement connection pooling for HTTP clients - Use appropriate timeouts and retry mechanisms - Monitor connection health and metrics - Implement graceful shutdown procedures2. Error Handling
- Handle network errors gracefully - Implement retry logic with exponential backoff - Log network errors for debugging - Provide meaningful error messages3. Performance Optimization
- Use connection pooling for high-throughput applications - Implement load balancing for distributed systems - Use compression for large payloads - Monitor network performance metrics4. Security
- Implement proper authentication and authorization - Use TLS/SSL for secure communications - Validate input data and sanitize outputs - Implement rate limiting to prevent abuse5. TuskLang Integration
- Use TuskLang configuration for network parameters - Implement network monitoring with TuskLang - Configure security settings through TuskLang - Use TuskLang for service discoveryNetworking patterns with TuskLang and Rust provide powerful tools for building high-performance, scalable network applications with comprehensive error handling and monitoring capabilities.