Room Registration
Each decentralized room performs self-registration with the Discovery Server on startup.
Registration Flow
1. Preparation (room side)
On startup, the room:
-
Reads its configuration:
DNS_HOST=discovery.example.comDNS_PORT=443ROOM_ID=room-1234MAX_PLAYERS=8GAME_MODE=raceREGION=us-east -
Generates or loads an X.509 certificate:
cert.pem (signed by the trusted CA)key.pem (private key) -
Generates an ECDH key pair for client-room security:
room_private_key (ECDH)room_public_key (ECDH), published in the registration
2. Registration Request (mTLS)
POST https://discovery.example.com:443/v1/discovery/register
Content-Type: application/json
{
"masked_token": "tok_room_1234",
"host": "192.168.1.100",
"port": 9000,
"protocol": "wss",
"max_players": 8,
"current_players": 0,
"game_mode": "race",
"region": "us-east",
"language": "en-US",
"version": "1.0.0",
"public_key_ecdh": "base64(...)",
"capabilities": [
"http",
"websocket",
"sse"
],
"tags": {
"difficulty": "hard",
"competitive": true
}
}
Security headers:
Client-Certificate: <X.509 cert>: the room's certificate- The connection uses mTLS: Discovery validates the certificate before processing the request
3. Validation in Discovery
4. Success Response
{
"status": "registered",
"masked_token": "tok_room_1234",
"lease_duration": 180,
"heartbeat_interval": 30,
"next_heartbeat_due": "2026-10-11T12:00:30Z",
"server_time": "2026-10-11T12:00:00Z"
}
Fields:
lease_duration: how long the room stays registered without a heartbeat (seconds)heartbeat_interval: recommended heartbeat frequencynext_heartbeat_due: when to send the next heartbeat to avoid a timeout
Registration Errors
| Code | Reason | Action |
|---|---|---|
400 Bad Request | Invalid or incomplete payload | Validate the request |
401 Unauthorized | Invalid or untrusted certificate | Check the certificate and CA |
409 Conflict | Room ID already registered | Use a unique ID or deregister the previous room |
413 Payload Too Large | Payload exceeds the limit | Reduce tags or metadata |
503 Service Unavailable | Discovery is down | Retry with exponential backoff |
Lease Renewal (Heartbeat)
After a successful registration, the room sends a periodic heartbeat:
POST https://discovery.example.com:443/v1/discovery/heartbeat
Content-Type: application/json
{
"masked_token": "tok_room_1234",
"current_players": 4,
"game_state": "in_progress",
"occurred_at": "2026-10-11T12:00:30Z"
}
Purpose:
- Renew the lease (180 seconds)
- Report the current number of players
- Signal that the room is alive
If a room sends no heartbeat for 180 seconds, Discovery removes it from the catalog.
Deregistration (Drain Mode)
Before shutting down, the room enters drain mode:
POST https://discovery.example.com:443/v1/discovery/drain
Content-Type: application/json
{
"masked_token": "tok_room_1234",
"reason": "planned_maintenance",
"drain_time_seconds": 60
}
Effect on Discovery:
- The room is marked as "draining" in the catalog.
- Clients receive a
draining: trueflag in the listing. - Clients know not to choose this room (new clients and clients already in the room are notified).
- The room keeps serving its existing players.
- After
drain_time_seconds, the room is removed from the registry.
This flow enables graceful shutdown without abrupt interruption.
Next: Room Listing