# openws-server
WebSocket server in Rust with room-based messaging, private messages, HTTP broadcast, and optional configuration. Designed as a standalone service that any frontend can consume.
## Installation
**From crates.io (recommended):**
```bash
cargo install openws-server
openws-server --host 0.0.0.0 --port 3000
```
**From GitHub:**
```bash
git clone https://github.com/benjamin0mar/openws-server.git
cd openws-server
cargo run -- --host 0.0.0.0 --port 3000
```
**With Docker:**
```bash
docker compose up
```
Server starts with configurable host and port via `--host` / `--port` flags, environment variables, or `openws.toml`. Defaults to `0.0.0.0:3000`.
## Protocol
Connect via WebSocket to `ws://localhost:3000/ws`. All messages are JSON with a `type` field.
### Client → Server
| `join` | `room`, `username` |
| `send` | `room`, `text` |
| `private` | `to`, `text` |
| `ping` | _(none)_ |
### Server → Client
| `joined` | `room`, `username` |
| `message` | `room`, `from`, `text`, `at` |
| `private` | `from`, `text` |
| `user_joined` | `room`, `username` |
| `user_left` | `room`, `username` |
| `error` | `code`, `message` |
| `pong` | _(none)_ |
## HTTP endpoints
| GET | `/health` | server health with room/client counts |
| GET | `/stats` | per-room breakdown |
| POST | `/api/broadcast` | send a message to a room via HTTP |
### Broadcast from your backend
```bash
curl -X POST http://localhost:3000/api/broadcast \
-H "Content-Type: application/json" \
-H "X-Api-Key: your-api-key" \
-d '{"room":"general","text":"hello from backend","from":"system"}'
```
The broadcast endpoint requires an API key set in `openws.toml` (or via `OPENWS_API_KEY` env var). The endpoint is disabled by default.
## Client library
Connect from any JavaScript/TypeScript frontend using the official client:
```bash
npm install @benjamin0mar/openws-client
```
Or clone from GitHub:
```bash
git clone https://github.com/benjamin0mar/openws-client-js.git
```
```js
import { OpenWS } from "@benjamin0mar/openws-client";
const ws = new OpenWS("ws://localhost:3000/ws");
await ws.join("general", "alice");
ws.on("message", (msg) => console.log(msg.from, msg.text));
```
## Configuration
Create a `openws.toml` file or use environment variables. Priority: env var > `openws.toml` > default.
```toml
[server]
host = "0.0.0.0"
port = 3000
[limits]
max_clients = 1000
max_rooms = 100
max_message_size = 8192
max_username_len = 32
[heartbeat]
ping_interval_secs = 30
pong_timeout_secs = 10
[broadcast]
api_key = ""
```
CLI flags: `--host`, `--port`, `--max-clients`, `--max-rooms`, `--max-message-size`, `--max-username-len`, `--ping-interval`, `--pong-timeout`, `--api-key`.
Environment variables: `OPENWS_HOST`, `OPENWS_PORT`, `OPENWS_MAX_CLIENTS`, `OPENWS_PING_INTERVAL`, `OPENWS_API_KEY`.
## Stack
Rust 2021 · Tokio · Axum · serde_json · tracing · config-rs · Docker