5.1 SSE 机制总览
SSE 响应为 text/event-stream,不经过 ApiResponseAdvice 统一包装。
连接由 chat.sse.executor 线程池异步驱动(8 核心 / 20 最大 / 500 队列,线程前缀 chat-sse-),
单连接超时 30 秒(SseEmitter(30_000L)),超时后推送 error 事件并关闭,客户端需自行重连。
event: start
data: {"messageId": 1001}
event: delta // 多次,逐段推送译文
data: {"delta": "Hello"} // 目标语言为 "en":8 字符/120ms;其他语言:16 字符/30ms
event: done
data: {"messageId": 1001, "translatedText": "Hello, how are you?"}
// 异常:event: error, data: "timeout"
⚠️ auto-reply 通道的 done 事件是纯文本(源语言完整回复),不是 JSON;
其流式过程为:先推 bot_start / bot_delta(AI 以目标语言回复,8 字符/120ms),
再推 delta(源语言翻译版本),最后 done = 源语言全文。
5.2 接口总览(前缀 /api/chat)
5.3 会话管理接口
/api/chat/sessions
创建翻译会话。
| 字段 | 类型 | 必填 | 校验 / 说明 |
|---|---|---|---|
sessionName | String | 必填 | 非空,≤ 100 字符 |
sourceLanguage | String | 必填 | 源语言代码 |
targetLanguage | String | 必填 | 目标语言代码 |
createdBy | String | 必填 | 创建者标识 |
description | String | 可选 | 会话描述 |
{
"sessionId": 7,
"sessionName": "客服咨询",
"sourceLanguage": "zh", "targetLanguage": "en",
"createdBy": "user-1",
"createdAt": "2026-09-06T10:00:00",
"status": "ACTIVE",
"participantCount": 1,
"messageCount": 0,
"lastActivity": "2026-09-06T10:00:00",
"description": "中英客服对话"
}
/api/chat/sessions?status=ACTIVE
查询会话列表。status 为可选过滤参数,取值为 SessionStatusEnum 枚举名(不区分大小写,内部 valueOf(upper)):ACTIVE / INACTIVE / ENDED / ARCHIVED。
/api/chat/sessions/{sessionId}
更新会话名称、语言对或描述(UpdateChatSessionRequest:sessionName / sourceLanguage / targetLanguage / description)。
/api/chat/sessions/{sessionId}/end
结束会话,状态置 ENDED。响应 data 为 null(仅以 success 判定)。
5.4 消息接口
/api/chat/messages
发送消息并同步返回完整翻译结果(SSE 通道不传参,消息体在此提交)。默认参数下同时入库并触发客服链路。
| 字段 | 类型 | 必填 | 默认值 | 校验 / 说明 |
|---|---|---|---|---|
sessionId | Long | 必填 | — | 目标会话 ID |
senderId | String | 必填 | — | 发送者标识 |
originalMessage | String | 必填 | — | 消息原文,非空且 ≤ 5000 字符 |
sourceLanguage | String | 必填 | — | 源语言 |
message | String | 可选 | — | 展示用消息内容 |
userId | Long | 可选 | — | 关联用户 ID |
userName | String | 可选 | — | 展示名;响应中优先取昵称,其次用户名 |
receiverId | String | 可选 | — | 接收者标识 |
targetLanguage | String | 可选 | en | 默认英文(默认参数源语言 zh / 目标 en) |
messageType | Integer | 可选 | 0 | 0=普通消息 |
useTerminology | Boolean | 可选 | — | 透传至翻译链路(含 RAG 术语增强) |
translationEngine | String | 可选 | — | 指定引擎 |
{
"messageId": 1001,
"sessionId": 7,
"userId": 1,
"userName": "小明",
"originalText": "你好,请问支持哪些语言?",
"translatedText": "Hello, which languages are supported?",
"sourceLanguage": "zh", "targetLanguage": "en",
"sentAt": "2026-09-06T10:01:00",
"messageType": 0,
"readBy": [ ]
}
消息保存走 sendChatMessage 完整链路:术语库(useTerminology)+ RAG 增强均生效,与文本翻译共用计费。
/api/chat/sessions/{sessionId}/messages
分页获取会话历史消息。
| 参数 | 必填 | 说明 |
|---|---|---|
page | 可选 | 默认 0(0 起始) |
size | 可选 | 默认 20 |
响应 data 为分页对象,元素结构同 ChatMessageResponse。
5.5 SSE 客户端完整示例
const sessionId = 7; const token = 'eyJhbGciOi...'; // 1. 建立 SSE 连接(EventSource 无法自定义 Header,浏览器端依赖 auth_token Cookie) const es = new EventSource(`/api/chat/sessions/${sessionId}/stream`); es.addEventListener('start', e => { console.log('翻译开始,消息 ID:', JSON.parse(e.data).messageId); }); es.addEventListener('delta', e => { const { delta } = JSON.parse(e.data); outputEl.appendText(delta); // 逐段追加渲染 }); es.addEventListener('done', e => { const { messageId, translatedText } = JSON.parse(e.data); console.log('完成:', translatedText); }); es.addEventListener('error', () => { es.close(); // 30 秒超时或服务端关闭 reconnect(); // 自行实现重连 }); // 2. 发送消息(fetch,与 SSE 连接解耦) await fetch('/api/chat/messages', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ sessionId, senderId: 'user-1', originalMessage: '你好,请问支持哪些语言?', sourceLanguage: 'zh', targetLanguage: 'en', useTerminology: true }) });
# 观察 SSE 事件流(连接保持 30 秒后超时) curl -N http://localhost:8090/api/chat/sessions/7/stream \ -H "Authorization: Bearer $TOKEN" # 另开终端发送消息,观察上方事件流输出 curl -X POST http://localhost:8090/api/chat/messages \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"sessionId":7,"senderId":"user-1","originalMessage":"你好","sourceLanguage":"zh","targetLanguage":"en"}' # AI 客服自动回复通道 curl -N http://localhost:8090/api/chat/sessions/7/auto-reply \ -H "Authorization: Bearer $TOKEN"