WebSocket 接口文档

  1. 端点信息

  2. URL: ws.cuzservice.vip

  3. 协议: WebSocket(支持 JSON 消息)。
  4. 认证: 要求 JWT token,通过以下方式传递:
  5. HTTP 头:Authorization: Bearer (建议方式)
  6. WebSocket 子协议:Sec-WebSocket-Protocol:
  7. URL 参数:?token=
  8. 空闲检测: 服务器配置了 60 秒空闲检测(IdleStateHandler),客户端需定期发送心跳以保持连接。
  9. 心跳机制

为保持 WebSocket 连接活跃,客户端需发送心跳消息,服务器会响应以确认连接状态。

  • 客户端发送:

json

json { "type": "UP_HEARTBEAT", "data": { "timestamp": long // 客户端时间戳(毫秒) } }

  • 服务器响应:

json

json { "type": "DOWN_HEARTBEAT", "data": { "timestamp": long // 服务器时间戳(毫秒) } }

  • 频率建议: 每 30 秒发送一次心跳,最大间隔不超过 60 秒以避免连接被服务器关闭。

  • 超时处理: 如果 60 秒内未收到客户端消息(包括心跳),服务器将关闭连接。

  • 认证机制

  • 认证方式: 客户端在建立 WebSocket 连接时需提供有效的 JWT token。

  • Token 获取:

  • 从登录接口获取 JWT token(具体接口由 TokenProvider 实现)。

  • Token 验证:

  • 服务器通过 TokenProvider 验证 token 签名。

  • 检查 Redis 中是否存在对应的 loginKey(由 TokenProvider.loginKey(token) 生成)。
  • 提取 token 中的 userId(Snowflake ID,Long 类型,表示坐席或临时用户)。

  • 失败处理:

  • 如果 token 缺失、无效或 Redis 中不存在,服务器返回错误消息并关闭连接:

    json

    json { "error": "未授权" // 或 "缺少 token", "无效 token", "Token 已过期或无效", "无效身份" }

  • 消息格式

所有 WebSocket 消息均为 JSON 格式,结构如下:

json

{
  "type": "string",
  "data": object
}
  • 字段说明:
  • type: 消息类型,枚举值见 WebSocketMessageType(如 UP_SEND_MESSAGE, DOWN_NEW_MESSAGE)。
  • data: 消息内容,具体结构取决于 type。

支持的消息类型

方向 类型 描述
上行 UP_AUTH 授权请求
上行 UP_SEND_MESSAGE 发送聊天消息
上行 UP_MARK_READ 标记会话消息为已读
上行 UP_HEARTBEAT 心跳消息
下行 DOWN_AUTH 授权响应
下行 DOWN_NEW_MESSAGE 新消息通知
下行 DOWN_MESSAGE_SENT 消息发送成功确认
下行 DOWN_MARK_READ 标记已读通知
下行 DOWN_HEARTBEAT 心跳响应
下行 DOWN_NEW_SESSION 新会话通知(会话转移)
下行 DOWN_ERROR 错误响应

UP_MARK_READ:消息进入可视区域:当用户滚动聊天窗口,消息出现在屏幕可视区域内时,可能会被标记为已读。这种方式常见于移动端或Web端聊天应用。

  1. 消息类型详情

5.1 上行消息

客户端调用示例

客户端需在连接建立后立即发送 UP_AUTH 消息:

json

{
  "type": "UP_AUTH",
  "data": {
    "token": "eyJhbGciOiJIUzUxMiJ9..."
  }
}

服务端响应(成功):

json

{
  "type": "DOWN_AUTH",
  "data": {
    "success": true,
    "message": "认证成功"
  }
}

服务端响应(失败):

json

{
  "type": "DOWN_AUTH",
  "data": {
    "success": false,
    "message": "无效 token"
  }
}

UP_SEND_MESSAGE(发送消息)

  • 描述: 客户端发送聊天消息到指定会话。

  • 请求格式:

json

json { "type": "UP_SEND_MESSAGE", "data": { "sessionId": long, // 会话 ID "content": string, // 消息内容 "lang":string } }

  • 响应:

  • 成功:DOWN_MESSAGE_SENT(确认消息已发送)。

  • 失败:DOWN_ERROR(如会话不存在或用户无权限)。

UP_MARK_READ(标记已读)

  • 描述: 客户端标记指定会话的消息为已读。

  • 请求格式:

json

json { "type": "UP_MARK_READ", "data": { "sessionId": long // 会话 ID } }

  • 响应:

  • 成功:DOWN_MARK_READ(通知会话参与者)。

  • 失败:DOWN_ERROR(如会话不存在或用户无权限)。

UP_HEARTBEAT(心跳)

  • 描述: 客户端发送心跳以保持连接。

  • 请求格式:

json

json { "type": "UP_HEARTBEAT", "data": { "timestamp": long // 客户端时间戳(毫秒) } }

  • 响应:

  • 成功:DOWN_HEARTBEAT。

  • 失败:DOWN_ERROR。

5.2 下行消息

DOWN_NEW_MESSAGE(新消息通知)

  • 描述: 通知接收者有新消息。

  • 格式:

json

json { "type": "DOWN_NEW_MESSAGE", "data": { "chat": { "id": long, // 消息 ID "sessionId": long, // 会话 ID "senderId": long, // 发送者 ID "receiverId": long, // 接收者 ID "content": string, // 消息内容 "sendTime": long, // 发送时间(毫秒) "isRead": boolean, // 是否已读 "chatType": integer // 消息类型(1: 会员-客服, 2: 临时用户-客服) }, "sessionId": long, // 会话 ID "unreadCount": integer // 该会话的未读消息数 } }

DOWN_MESSAGE_SENT(消息发送成功)

  • 描述: 确认客户端发送的消息已保存。

  • 格式:

json

json { "type": "DOWN_MESSAGE_SENT", "data": { "chatId": long, // 消息 ID "sessionId": long, // 会话 ID "sendTime": long // 发送时间(毫秒) } }

DOWN_MARK_READ(标记已读通知)

  • 描述: 通知会话参与者消息已标记为已读。

  • 格式:

json

json { "type": "DOWN_MARK_READ", "data": { "sessionId": long // 会话 ID } }

DOWN_HEARTBEAT(心跳响应)

  • 描述: 服务器响应客户端心跳。

  • 格式:

json

json { "type": "DOWN_HEARTBEAT", "data": { "timestamp": long // 服务器时间戳(毫秒) } }

DOWN_QUERY_UNREAD(未读消息数查询结果)

  • 描述: 返回用户所有会话的未读消息数。

  • 格式:

json

json { "type": "DOWN_QUERY_UNREAD", "data": [ { "sessionId": long, // 会话 ID "unreadCount": integer // 未读消息数 } // ... 更多会话 ] }

DOWN_NEW_SESSION(新会话通知)

  • 描述: 通知用户有新的会话(新临时客户进入及转接)。

  • 格式:

json

json { "type": "DOWN_NEW_SESSION", "data": { "session": { "id": long, // 会话 ID "userId": long, // 用户 ID(坐席) "tempUserId": long, // 临时用户 ID "status": integer // 会话状态(1: 活跃) // 其他会话字段 } } }

DOWN_ERROR(错误响应)

  • 描述: 返回错误信息。

  • 格式:

json

json { "type": "DOWN_ERROR", "data": { "code": string, // 错误码(如 "UNAUTHORIZED", "SESSION_NOT_FOUND") "message": string // 错误描述 } }

  • 错误码
错误码 描述
UNAUTHORIZED 未认证或用户无权限
SESSION_NOT_FOUND 会话不存在或已关闭
INVALID_TYPE 未知的消息类型
INVALID_RECIPIENT 接收者未指定
PROCESS_ERROR 处理消息失败
SERVER_ERROR 服务器内部错误
  1. 使用示例

7.1 建立连接

javascript

const ws = new WebSocket('ws://<your-server>:8081/ws', ['<jwt-token>']);

// 或者使用 URL 参数
// const ws = new WebSocket('ws://<your-server>:8081/ws?token=<jwt-token>');

ws.onopen = () => {
  console.log('Connected');
  // 启动心跳
  setInterval(() => {
    ws.send(JSON.stringify({
      type: 'UP_HEARTBEAT',
      data: { timestamp: Date.now() }
    }));
  }, 30000);
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  console.log('Received:', msg);
};

ws.onclose = () => console.log('Disconnected');

7.2 发送消息

json

{
  "type": "UP_SEND_MESSAGE",
  "data": {
    "sessionId": 123,
    "content": "Hello, how can I help you?"
  }
}

7.3 标记已读

json

{
  "type": "UP_MARK_READ",
  "data": {
    "sessionId": 123
  }
}

7.4 查询未读消息数

json

{
  "type": "UP_QUERY_UNREAD",
  "data": {}
}
  1. 注意事项

  2. 认证要求: 确保提供有效的 JWT token,否则连接将被拒绝。

  3. 心跳频率: 每 30 秒发送一次心跳,最大间隔不超过 60 秒。
  4. 会话状态: 仅活跃会话(status=1)支持消息发送和标记已读。
  5. 未读消息数: UP_QUERY_UNREAD 返回所有相关会话的未读消息数,需检查 sessionId。