使用 STOMP over WebSocket,前端通过 @stomp/stompjs 库连接。
ws://localhost:8080/ws/chat
连接时在 Header 中携带 Token:
const client = new Client({
brokerURL: 'ws://localhost:8080/ws/chat',
connectHeaders: {
Authorization: 'Bearer ' + token
}
});
| 频道 | 说明 |
|---|---|
/topic/session/{sessionNo} |
订阅指定会话的消息(双端均订阅) |
/user/queue/notify |
用户私有通知(新消息提醒、状态变更) |
/topic/seat/status |
坐席在线状态变更广播 |
{
"type": "MSG",
"msgType": "text",
"msgNo": "MSG_uuid_123",
"sessionId": 1,
"senderId": 5,
"senderName": "客服小A",
"senderAvatar": "https://...",
"senderRole": "waiter",
"content": "您好!请问有什么可以帮助您的?",
"sendTime": "2024-03-16 13:16:05"
}
{
"type": "MSG",
"msgType": "image",
"msgNo": "MSG_uuid_124",
"sessionId": 1,
"senderId": 5,
"senderRole": "waiter",
"fileUrl": "https://minio.host/chat/2024/img_xxx.jpg",
"fileName": "截图.jpg",
"fileSize": 102400,
"sendTime": "2024-03-16 13:16:10"
}
{
"type": "MSG",
"msgType": "file",
"msgNo": "MSG_uuid_125",
"sessionId": 1,
"fileUrl": "https://minio.host/chat/2024/doc_xxx.pdf",
"fileName": "审计报告.pdf",
"fileSize": 2048000,
"fileType": "application/pdf",
"sendTime": "2024-03-16 13:16:15"
}
{
"type": "MSG",
"msgType": "job_card",
"msgNo": "MSG_uuid_126",
"sessionId": 1,
"senderRole": "waiter",
"payload": {
"jobId": 501,
"title": "审计员",
"salary": "13K-23K",
"tags": ["实习", "五险一金", "985"],
"company": "华财仁合",
"location": "上海市·黄浦区",
"urgency": "急招",
"quota": "1 人",
"deadline": "2025-12-12 24:00"
},
"sendTime": "2024-03-16 13:15:56"
}
{
"type": "MSG",
"msgType": "order_card",
"msgNo": "MSG_uuid_127",
"sessionId": 1,
"senderRole": "waiter",
"payload": {
"orderCardId": 5,
"name": "审计师一级入职定金",
"price": "29.9",
"status": "pending",
"expireTime": "2024-03-16 13:17:10",
"countdownSeconds": 60
},
"sendTime": "2024-03-16 13:16:10"
}
当 60 秒倒计时结束,服务端自动广播:
{
"type": "ORDER_CARD_EXPIRE",
"sessionId": 1,
"orderCardId": 5,
"status": "expired",
"expireTime": "2024-03-16 13:17:10"
}
{
"type": "READ_RECEIPT",
"sessionId": 1,
"readerId": 10001,
"lastReadMsgId": 99,
"readTime": "2024-03-16 13:18:00"
}
{
"type": "SYSTEM",
"content": "客服已接入,请稍候..."
}
import { Client } from '@stomp/stompjs';
const chatClient = new Client({
brokerURL: 'ws://localhost:8080/ws/chat',
connectHeaders: { Authorization: 'Bearer ' + token },
onConnect: () => {
// 订阅会话消息频道
chatClient.subscribe(`/topic/session/${sessionNo}`, (msg) => {
const data = JSON.parse(msg.body);
handleIncomingMessage(data);
});
}
});
chatClient.activate();
// 发送消息
function sendTextMessage(content) {
chatClient.publish({
destination: '/app/chat/send',
body: JSON.stringify({
msgType: 'text',
sessionId: sessionId,
msgNo: generateUUID(),
content: content
})
});
}