A horizontally scalable WebSocket server built with Go. Multiple server instances coordinate through Redis (connection registry) and RabbitMQ (message routing via topic exchange) to deliver messages between users regardless of which server they are connected to.
- Each server instance maintains its own local WebSocket connections.
- When a user connects, their
userIDand theserverIDthey connected to are stored in Redis. - When a user sends a message to another user:
- The server checks if the target user is connected locally. If so, it delivers directly.
- Otherwise, it looks up the target user's server in Redis and publishes the message to RabbitMQ with a routing key of
server.{targetServerID}.
- Each server subscribes to its own routing key and delivers incoming messages to the appropriate local WebSocket connection.
- Go 1.26+
- Docker (for Redis and RabbitMQ)
- Air (optional, for hot-reloading during development)
docker compose up redis rabbitmq -dCopy the example env file and fill in the values:
cp .env.example .envgo run cmd/main.goOr with Air for hot-reloading:
airTerminal 1:
SERVER_ID=server-1 PORT=:8080 go run cmd/main.goTerminal 2:
SERVER_ID=server-2 PORT=:8081 go run cmd/main.godocker compose up --buildConnect to the WebSocket endpoint with a user ID:
ws://localhost:8080/ws?user_id=alice
Send a message to another user:
{ "to": "bob", "body": "hello" }The recipient receives:
{ "from": "alice", "to": "bob", "body": "hello" }cmd/
main.go - Application entry point
api/ - HTTP routes
ws/ - WebSocket handler and message routing
config/
cache/ - Redis client initialization
file/ - File path utilities
internal/
adapter/ - Interface implementations (Redis, RabbitMQ)
domain/ - Interfaces and domain types
service/ - Business logic layer
pkg/
env/ - Environment variable loading
errors/ - Custom error types
response/ - HTTP response helpers
util/ - Utilities (server ID, panic helpers)
See .env.example for the full list. Key variables for the distributed socket functionality:
| Variable | Description | Default |
|---|---|---|
PORT |
HTTP server port | :5000 |
SERVER_ID |
Unique identifier for this server instance | hostname |
REDIS_ADDR |
Redis address | (required) |
REDIS_PASSWORD |
Redis password | (required) |
RABBITMQ_ADDR |
RabbitMQ address | (required) |
RABBITMQ_PASSWORD |
RabbitMQ password | (required) |