Client integration
Xshathra Realtime (Centrifugo behind /realtime) carries WebSocket traffic for your apps. The console gives each project a server_api_key / client_api_key pair for your product (HTTP publish proxy, app identity). Use server_api_key on trusted backends to call Xshathra token and publish endpoints. Deployment engine secrets stay internal.
1. Create a project and copy your keys
Sign in at /login, open the dashboard, and create a project (e.g. production vs staging). Each project has one key pair: server_api_key and client_api_key. Keep server_api_key on servers you control only; never ship it in a browser or mobile binary.
2. WebSocket URL (same origin as the app)
Use TLS in production. The path is fixed:
wss://YOUR_HOST/realtime/connection/websocket
Local dev (Next on 3001): ws://localhost:3001/realtime/connection/websocket. Set NEXT_PUBLIC_XSHATHRA_REALTIME_URL in the app env to the full ws: or wss: URL for browser clients.
Server publish from your backend (project key): POST https://YOUR_HOST/api/realtime/publish with Authorization: apikey YOUR_SERVER_API_KEY. For private channel joins, mint subscription JWTs with POST /api/realtime/subscription-token — see API.
3. Get tokens from Xshathra
After authenticating your app user, your backend requests short-lived realtime tokens from Xshathra using the project server_api_key.
POST https://YOUR_HOST/api/realtime/token
Authorization: apikey YOUR_SERVER_API_KEY
Content-Type: application/json
{
"userId": "user_123",
"ttlSeconds": 900,
"channels": ["public:lobby"]
}POST https://YOUR_HOST/api/realtime/subscription-token
Authorization: apikey YOUR_SERVER_API_KEY
Content-Type: application/json
{
"userId": "user_123",
"channel": "chat:proj_123:room_abc",
"ttlSeconds": 900
}Response:
{
"token": "eyJhbGciOi...",
"expiresInSeconds": 900
}Pass that token to the client over HTTPS. Centrifugo expects the connection JWT in the first protocol connect frame (what centrifuge-js sends when you set token in the client options), not as a raw ?token= query on the WebSocket URL — that pattern often fails the upgrade with HTTP 400. WebSocket URL:
wss://YOUR_HOST/realtime/connection/websocket
Centrifuge-compatible clients (e.g. centrifuge-js) accept a token in the constructor — see the client connection token section in Centrifugo docs.
CLI smoke test:
The engine negotiates the WebSocket subprotocol centrifuge-json (see Centrifuge's handler_websocket.go). Tools must send Sec-WebSocket-Protocol: centrifuge-json. If you see HTTP 400 on connect, your edge proxy (often Apache) may be forwarding /realtime as plain HTTP instead of tunneling the upgrade — enable WebSocket proxying (e.g. mod_proxy_wstunnel, ws:// rewrite + [P,L], preserve Upgrade / Connection).
TOKEN=$(curl -sS -X POST "https://YOUR_HOST/api/realtime/token" \
-H "Authorization: apikey YOUR_SERVER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"userId":"user_123"}' | jq -r .token)
# If curl cannot reach the host: HTTPS_PROXY=http://127.0.0.1:10808 curl ... or ALL_PROXY=socks5h://127.0.0.1:10808 curl ...
npx wscat \
-H "Sec-WebSocket-Protocol: centrifuge-json" \
-c "wss://YOUR_HOST/realtime/connection/websocket?cf_ws_frame_ping_pong=true"
# After Connected, paste (use the TOKEN variable value as the JSON string):
{"id":1,"connect":{"token":"PASTE_JWT_HERE"}}Xshathra signs and validates engine-facing JWT details server-side. Your integration only needs project keys and these first-party endpoints.
4. Patterns for games and apps
- Match / room channel — one channel per match; server publishes state ticks; clients subscribe after matchmaking assigns them.
- Lobby or presence — lightweight channels for party invites, ready checks, or “who is online” using realtime presence where enabled.
- Global announcements — broadcast channels for maintenance or version banners; validate publish only on your backend.
- Non-game apps — same model: collaboration sessions, live cursors, or dashboards; keep authoritative writes on the server.
Related
- Chat application example — step-by-step room chat on the data plane.
- Game and matchmaking example — match channels, authoritative server, and matchmaking flow.
- API reference — token, subscription-token, publish, and realtime paths.
- Centrifugo — engine concepts and manual pointers.
