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

80 lines
1.7 KiB
Markdown
Raw Normal View History

# Socket.IO chat contract
## Connection
Connect to the Complex API namespace:
```text
http://localhost:3002/chat
```
The browser must already have a valid `demo_session` cookie and use credentials. Both `websocket` and `polling` transports are enabled.
```ts
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`
```json
{
"organizationId": "org-acme",
"conversationId": "conversation-support"
}
```
Response event: `chat:joined`.
### `chat:leave`
Uses the same payload. Response event: `chat:left`.
### `message:send`
```json
{
"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`:
```json
{
"conversationId": "conversation-support",
"userId": "complex-user-support"
}
```
## Error event
`chat:error` always contains a stable shape:
```json
{
"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.