WebSocket消息协议.md 3.7 KB

WebSocket 消息协议说明

连接方式

使用 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": "客服已接入,请稍候..."
}

前端接入示例(Vue3)

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
    })
  });
}