Files
slm-design/examples/demo-backend/docs/WEBSOCKET.md

1.7 KiB

Socket.IO chat contract

Connection

Connect to the Complex API namespace:

http://localhost:3002/chat

The browser must already have a valid demo_session cookie and use credentials. Both websocket and polling transports are enabled.

import { io } from "socket.io-client";

const socket = io("http://localhost:3002/chat", {
  withCredentials: true,
});

An invalid session receives chat:error and is disconnected.

Client events

chat:join

{
  "organizationId": "org-acme",
  "conversationId": "conversation-support"
}

Response event: chat:joined.

chat:leave

Uses the same payload. Response event: chat:left.

message:send

{
  "organizationId": "org-acme",
  "conversationId": "conversation-support",
  "text": "Can you check this order?",
  "clientMessageId": "frontend-generated-uuid"
}

Response event: message:ack. Room broadcast: message:created.

Sending the same clientMessageId again returns the existing message. Frontends should also deduplicate incoming message:created by server message id.

typing:start and typing:stop

Use the chat:join payload. Other room members receive typing:started or typing:stopped:

{
  "conversationId": "conversation-support",
  "userId": "complex-user-support"
}

Error event

chat:error always contains a stable shape:

{
  "code": "CHAT_OPERATION_FAILED",
  "message": "Conversation not found."
}

Reconnect expectations

After reconnect, the frontend should join active conversations again and reload messages after its last known cursor. A session expired by POST /api/v1/testing/session/expire rejects the next Socket.IO connection.