Chat application example

This walkthrough shows how to build a room-based chat on top of Xshathra's data plane: one realtime channel per room, short-lived connection tokens from your backend, and a simple JSON message shape. It mirrors the patterns described in Client integration.

What you will have at the end

  • A channel name per chat room (e.g. party, match lobby, support thread).
  • A browser or game client that connects to Xshathra Realtime with a JWT from your API.
  • A message envelope every subscriber understands (text, sender id, timestamp).

Before you start

  1. A project in the console (dashboard) with server_api_key and client_api_key — keep server_api_key on the backend only.
  2. Xshathra Realtime at ws://localhost:3001/realtime/connection/websocket in local dev. In production, wss://your-domain/realtime/connection/websocket.
  3. A small backend you control (Node, Go, etc.) that signs connection JWTs with server_api_key per Xshathra docs.

Step 1 — Pick a channel naming scheme

Use predictable, unique names so clients cannot guess other rooms. Include your Xshathra project id in the string to avoid collisions across environments.

# Pattern
chat:{projectId}:{roomId}

# Examples
chat:proj_01HZZZZZZZZZZZZZZZZZZZZZZ:room_abc123
chat:proj_01HZZZZZZZZZZZZZZZZZZZZZZ:match_7f3a

Treat roomId as an opaque id issued by your matchmaking or chat service, not as user-supplied free text.

Step 2 — Mint a connection token (backend)

After you authenticate the user (session cookie, platform ticket, etc.), create a realtime connection JWT with a short TTL (minutes). Put the token sub (user id) in claims; optionally add channels for default subscriptions or use subscription tokens per channel (stricter).

Sign with server_api_key from the console; claim names follow Xshathra's token rules in Client integration.

// Pseudocode: POST /api/realtime/token → { "token": "..." }
// 1. Verify your own session.
// 2. Build realtime JWT (HS256 with token secret).
// 3. sub = stable user id; exp = now + 15m.
// 4. Return token to the client over HTTPS.

Step 3 — (Recommended) Lock down the chat channel

For private rooms, configure the channel so clients cannot subscribe without a subscription JWT. Your backend issues that JWT only when the user is allowed in the room (party member, match participant, etc.).

Step 4 — Connect from the browser

Use a WebSocket client compatible with Xshathra Realtime (see client integration). Fetch a fresh token from your API, then connect.

// Pseudocode (browser)
const res = await fetch("/api/realtime/token", { credentials: "include" });
const { token } = await res.json();

// wsUrl = NEXT_PUBLIC_XSHATHRA_REALTIME_URL (full wss://.../realtime/connection/websocket)
// const connection = yourClient.connect(wsUrl, { token });

const channel = "chat:proj_xxx:room_abc123";
// subscribe to channel; on message -> appendToUi(envelope)

Step 5 — Publish messages

Production chat: send text to your REST API; the server validates, persists if needed, then publishes via Xshathra publish API at POST https://your-app.example/api/realtime/publish (same origin as the WebSocket) using server_api_key so clients cannot spoof senders or bypass moderation.

Prototypes: client-side publish can be enabled on the channel for speed, but treat it as insecure — anyone with a token could publish arbitrary payloads.

Step 6 — Use one JSON shape everywhere

Keep a single envelope so UI and bots stay simple. Extend with a type field when you add system events (user joined, typing, etc.).

{
  "type": "chat.message",
  "id": "01HMXXXX",
  "roomId": "room_abc123",
  "senderId": "user_01H...",
  "text": "Hello from the data plane",
  "sentAt": "2026-03-24T12:00:00.000Z"
}

Step 7 — Optional next steps

  • Presence — show who is in the room (realtime presence on the same channel).
  • History — enable stream history for late joiners; cap size and TTL for GDPR and storage.
  • Moderation — rate limits and word filters on the server before publish.

Related