A lightweight WebSocket proxy server written in Go that forwards connections to backend servers using the ObjectLink protocol. Features message logging, tracing, a web UI for monitoring, and a JavaScript scripting system for interacting with WebSocket streams.
- Forward WebSocket connections to backend servers
- Multiple proxy configurations with different modes:
- Proxy mode: Forward to a backend WebSocket server
- Echo mode: Built-in echo server for testing
- Backend script mode: JavaScript-powered custom backends
- Embedded NATS message bus for internal routing (no external dependencies)
- Message delays and speed throttling for testing
- JSON and YAML config formats
- Verbose logging (messages to console)
- Trace logging (messages to
.jsonlfiles with rotation) - Watch mode (auto-reload on config change)
- Health check endpoint with statistics
- Web UI for monitoring and configuration
- Automatic retry with exponential backoff on backend connection failure
# Using go
go build -o wsproxy ./cmd/wsproxy
# Using taskfile
task build
# Cross-compile for all platforms
task build:allgo install ./cmd/wsproxy
# Or using taskfile
task install# Run with default config (proxy.yaml)
./wsproxy
# Run with specific config file
./wsproxy -c proxy.yaml
# Run with verbose logging (messages to console)
./wsproxy -v
# Run with trace logging (messages to .jsonl files)
./wsproxy -t
# Run with watch mode (reload on config change)
./wsproxy -w
# Enable web UI
./wsproxy --ui :8080
# Enable health check endpoint
./wsproxy --health :8081
# Specify trace directory
./wsproxy -t --trace-dir /var/log/wsproxy
# Combine flags
./wsproxy -c proxy.yaml -v -t -w --ui :8080 --health :8081
# Show version
./wsproxy --version| Flag | Short | Description |
|---|---|---|
--config |
-c |
Path to config file (default: proxy.yaml) |
--verbose |
-v |
Log all messages to console |
--trace |
-t |
Write all messages to JSONL files |
--watch |
-w |
Watch config file and reload on changes |
--ui |
Web UI server address (e.g., :8080) |
|
--health |
Health check server address (e.g., :8081) |
|
--trace-dir |
Directory for trace files (or WSPROXY_TRACE_DIR env) |
|
--version |
Show version information | |
--help |
-h |
Show help |
Start a simple WebSocket echo server:
wsproxy echo # Default ws://localhost:5556/ws
wsproxy echo --addr :5556 --verbose # Custom port with loggingStream messages from a JSONL file over WebSocket:
wsproxy play traffic.jsonl --url ws://localhost:5560/ws --rate 100
wsproxy play traffic.jsonl --loop --delay 1000 # Loop with 1s delayConfiguration can be in JSON or YAML format (auto-detected by file extension).
verbose: false
trace: false
watch: false
traceDir: "/tmp/wsproxy/traces"
traceConfig:
maxSizeMB: 10
maxBackups: 5
maxAgeDays: 7
compress: true
web:
listen: ":8080"
proxies:
# Proxy mode - forward to backend
server:
listen: ":5557"
backend: ws://localhost:5556/ws
delayToClient: 0 # ms delay for responses
delayFromClient: 0 # ms delay for requests
speed: 1.0 # Speed factor (0.01-1.0, 1.0 = normal)
maxBufferSize: 1000 # Max queued messages for throttling
# Echo mode - built-in echo server
test:
listen: ":5558"
mode: echo
# Backend script mode - JavaScript backend
mock:
listen: "ws://localhost:5560/ws" # Listen address (script starts server here)
mode: backend
backendScript: mock # Script name from scripts/ directory| Option | Description |
|---|---|
listen |
Address to listen on (e.g., :8080 or ws://localhost:8080/ws) |
backend |
WebSocket URL to forward to (required for proxy mode) |
mode |
proxy (default), echo, or backend |
backendScript |
Script name for backend mode (from scripts/ directory) |
delayToClient |
Delay in ms for messages to client |
delayFromClient |
Delay in ms for messages from client |
speed |
Speed factor 0.01-1.0 (1.0 = normal, 0.5 = half speed) |
maxBufferSize |
Max queued messages before dropping (default: 1000) |
| Option | Description |
|---|---|
maxSizeMB |
Max file size before rotation (default: 10) |
maxBackups |
Max old files to keep (default: 5) |
maxAgeDays |
Max age in days (default: 7) |
compress |
Compress rotated files (default: true) |
When enabled with --ui :8080, the web UI provides:
- Dashboard: Real-time stats and quick actions
- Proxies: Proxy management (add, edit, delete)
- Clients: Client connection management
- Scripting: Script editor (client and backend scripts)
- Live Stream: Real-time message stream view
- Stream Editor: Timeline, filters, markers, JQ queries
- Stream Files: Trace file browser
- Stream Player: Replay trace files to proxies
- Logging: Application log viewer
- Settings: Runtime settings
When trace mode is enabled (-t or trace: true), messages are written to {proxy-name}.jsonl files with automatic rotation:
{"ts":1701523200123,"dir":"SEND","msg":{"type":"request","id":1}}
{"ts":1701523200456,"dir":"RECV","msg":{"type":"response","id":1}}| Field | Description |
|---|---|
ts |
Timestamp in milliseconds (epoch) |
dir |
Direction: SEND (client to backend) or RECV (backend to client) |
msg |
The JSON message |
When enabled with --health :8081:
| Endpoint | Description |
|---|---|
GET /health |
Full status with statistics |
GET /ready |
Kubernetes readiness probe |
GET /live |
Kubernetes liveness probe |
| Stat | Description |
|---|---|
uptime_seconds |
Time since server start |
connections_total |
Total connections opened |
connections_active |
Current active connections |
connections_failed |
Failed backend connections |
messages_in |
Messages from client to backend |
messages_out |
Messages from backend to client |
bytes_in |
Total bytes received from clients |
bytes_out |
Total bytes sent to clients |
task build # Build the binary
task build:all # Build for all platforms
task run # Run with default config
task run:verbose # Run with verbose logging
task run:trace # Run with trace logging
task run:watch # Run with watch mode
task clean # Remove binary and .jsonl files
task fmt # Format code
task lint # Run linter
task test # Run tests
task tidy # Tidy go modules
task install # Install to GOPATH/binMIT