3.4 KiB
轻松聘聊天实时接口
本文补充 openapi-rc.json 中的消息发送、事件补拉和消息字段。所有 HTTP 路径以 /api/v1 为前缀;下文省略该前缀。
连接和发送
通过 STOMP WebSocket 连接 /api/v1/ws,在 STOMP CONNECT 帧中设置 Authorization: Bearer <accessToken>。不得放在 URL 中,refresh token 不可代替 access token。连接成功后订阅唯一用户队列 /user/queue/chat-events,收到 {"type":"CHAT_READY"} 后开始补拉。业务消息继续通过 HTTP 接口发送,STOMP SEND 不开放。
POST /conversations/messages 请求:
{
"conversationId": 1,
"content": "你好",
"clientMessageId": "example-message-001"
}
clientMessageId 为 1–64 位英文字母、数字、下划线或连字符;为兼容旧客户端可省略,但新客户端必须为一次逻辑发送生成固定标识,并在超时、断线或未收到响应时复用。同一会话、同一发送者下,相同标识和正文返回原消息,不重复生成事件;相同标识搭配不同正文返回 400。撤回后重试也不会恢复旧正文。
消息响应增加 clientMessageId(旧消息可为空)和 version(消息版本)。MessageResponse 在普通会话返回 senderUserId;人才邀请会话继续使用 senderScope 隐藏用户标识。撤回消息只返回“消息已撤回”占位。
事件补拉
GET /conversations/{id}/events?after=0&size=50 必须携带普通 HTTP Bearer access token,且当前账号必须属于该会话。after 是非负事件游标;size 默认 50,合法范围 1–100。
响应的 data:
{
"items": [
{
"eventId": 2,
"type": "MESSAGE_CREATED",
"conversationId": 1,
"occurredAt": "2026-10-15T10:00:00",
"actorScope": "OTHER_PARTICIPANT",
"payload": {
"id": 1,
"clientMessageId": "example-message-001",
"version": 0,
"conversationId": 1,
"content": "你好",
"status": "SENT",
"isRead": false
}
}
],
"nextCursor": 2,
"hasMore": false
}
事件包括 MESSAGE_CREATED、MESSAGE_READ、MESSAGE_RECALLED。actorScope 为 CURRENT_USER 或 OTHER_PARTICIPANT;payload.isRead 表示当前接收用户的已读状态。payload 读取消息当前状态,而不是保存历史正文快照。
客户端按以下顺序恢复:
- 连接、鉴权、订阅并等待
CHAT_READY。 - 使用该账号、该会话已持久化的补拉游标调用事件接口;首次使用 0。
- 以
eventId去重,以消息id和version合并,避免旧版本覆盖新状态。 - 本页成功合并后才持久化
nextCursor;hasMore=true时继续请求,直到为 false。 - 补拉期间同时合并实时事件。实时事件 ID 可能乱序,不得直接用其最大值推进补拉游标。同版本的已读状态还需按
actorScope和本地已读操作处理,不能仅按版本丢弃已读事件。
断线后重新获取有效 access token、重连、订阅,再重复上述流程。账号切换必须隔离游标、消息缓存和连接。
运行边界
这些接口沿用企业认证、会话成员、屏蔽和现有匹配准入规则;不会改变投递或开聊门槛。目前 WebSocket 使用单实例内存 broker,多实例部署需要共享消息分发能力。Nginx 示例文件须经部署配置和验证后才能使用。