Skip to main content

Module ws_proxy

Module ws_proxy 

Source
Expand description

WebSocket reverse proxy.

WsProxy listens for incoming TCP connections, reads the initial HTTP request, verifies it is a WebSocket upgrade, connects to a backend, performs the WebSocket handshake end-to-end, and then bidirectionally tunnels raw WebSocket bytes between the client and the backend.

Plain (ws://) backends use two threads (one per direction) via std::io::copy, identical to the original implementation.

TLS (wss://) backends use a single-thread polling loop: both streams are set to a 5 ms read timeout and the loop alternates between the two directions, sleeping 1 ms when neither side has data. This avoids the deadlock that arises when trying to share a rustls::StreamOwned between two blocking threads.

§Health checks

WsProxy::new treats every configured backend as always live — matching the original behavior, with no background monitoring. The config-driven proxy’s [ws_proxy.health_check] (see spec/PROXY_SERVER_CONFIG.md) opts a [[ws_proxy]] block into the same background health checker used for [[upstream]] pools (proxy_config::health::start_health_checker), which periodically probes each backend with a plain HTTP GET and removes it from rotation after enough consecutive failures. If every backend is currently unhealthy, new WebSocket upgrade attempts get 503 Service Unavailable instead of being routed to a backend known to be down.

§Example

use rust_web_server::ws_proxy::WsProxy;

// Plain WebSocket — two backends, round-robin.
WsProxy::new(["ws://chat-backend:9000", "ws://chat-backend:9001"])
    .connect_timeout_ms(3000)
    .bind("0.0.0.0:8080")
    .unwrap();

// TLS WebSocket (requires http-client or http2 feature).
WsProxy::new(["wss://chat-backend.internal:443"])
    .bind("0.0.0.0:8080")
    .unwrap();

Structs§

WsProxy
WebSocket reverse proxy with round-robin load balancing.