219 行
8.0 KiB
Markdown
219 行
8.0 KiB
Markdown
|
|
# XuqmGroup Vue3 SDK 测试报告
|
|||
|
|
|
|||
|
|
> **生成时间**: 2026-04-30
|
|||
|
|
> **测试环境**: Node.js v22.22.2, macOS
|
|||
|
|
> **服务端**: 192.168.113.37 (本地 IntelliJ 启动)
|
|||
|
|
> **参考文档**: `/Users/xuqinmin/Projects/XuqmGroup/ANDROID_SDK_DEBUG.md`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、测试概览
|
|||
|
|
|
|||
|
|
| 类别 | 数量 | 通过 | 失败 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| 单元测试 | 39 | 39 | 0 |
|
|||
|
|
| 集成测试 (E2E) | 36 | 36 | 0 |
|
|||
|
|
| **总计** | **75** | **75** | **0** |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、发现的 Bug 及修复
|
|||
|
|
|
|||
|
|
### 🔴 Bug 1: ImClient 未实现 STOMP 协议
|
|||
|
|
|
|||
|
|
**现象**: WebSocket 连接成功,但发送消息后服务端不处理,history 中无记录,无实时推送。
|
|||
|
|
**根因**: Vue3 SDK 的 `ImClient.ts` 发送的是自定义 JSON 格式:
|
|||
|
|
```json
|
|||
|
|
{"destination": "/app/chat.send", "payload": {...}}
|
|||
|
|
```
|
|||
|
|
而服务端 Spring STOMP 期望标准 STOMP 协议帧:
|
|||
|
|
```
|
|||
|
|
SEND\ndestination:/app/chat.send\ncontent-type:application/json\n\n{body}\x00
|
|||
|
|
```
|
|||
|
|
**修复**: 重写 `ImClient.ts`,完整实现 STOMP 协议:
|
|||
|
|
- CONNECT / CONNECTED 握手
|
|||
|
|
- SEND 帧发送消息
|
|||
|
|
- SUBSCRIBE 自动订阅 `/user/queue/messages`
|
|||
|
|
- MESSAGE / ERROR 帧解析
|
|||
|
|
- DISCONNECT 优雅关闭
|
|||
|
|
|
|||
|
|
**状态**: ✅ 已修复并验证
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 🔴 Bug 2: CONNECT 帧缺少 Authorization Header
|
|||
|
|
|
|||
|
|
**现象**: STOMP 连接后发送消息,服务端 principal 为 null,消息被静默丢弃。
|
|||
|
|
**根因**: 服务端 `WebSocketConfig.java` 从 STOMP CONNECT 帧的 `Authorization` header 提取 token:
|
|||
|
|
```java
|
|||
|
|
String token = accessor.getFirstNativeHeader("Authorization");
|
|||
|
|
```
|
|||
|
|
而 Vue3 SDK 的 `connect()` 未在 CONNECT 帧中携带 `Authorization: Bearer <token>` header。
|
|||
|
|
|
|||
|
|
**Android SDK 对比**: Android SDK 的 `sendConnectFrame` 明确包含了:
|
|||
|
|
```kotlin
|
|||
|
|
"Authorization" to "Bearer $token"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修复**: `ImClient.ts` 的 `connect()` 方法在构建 CONNECT 帧时添加:
|
|||
|
|
```typescript
|
|||
|
|
const token = getToken()
|
|||
|
|
if (token) headers['Authorization'] = `Bearer ${token}`
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**状态**: ✅ 已修复并验证
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 🔴 Bug 3: connect() 中 token 未捕获,存在竞态条件
|
|||
|
|
|
|||
|
|
**现象**: 多客户端场景下,clientA 发送消息时使用错误的 token,导致认证失败。
|
|||
|
|
**根因**: `connect()` 在 `onopen` 回调中调用 `getToken()` 获取当前 token。如果全局 token 在 clientA 连接建立前被其他客户端覆盖,clientA 会使用错误的 token 发送 CONNECT 帧。
|
|||
|
|
|
|||
|
|
**修复**: 在 `connect()` 方法**入口处**立即捕获 token 和 URL,后续 `onopen` 回调使用捕获值:
|
|||
|
|
```typescript
|
|||
|
|
connect(): void {
|
|||
|
|
const token = getToken() // 立即捕获
|
|||
|
|
const url = `${config.wsUrl || DEFAULT_IM_WS_URL}?token=${token ?? ''}`
|
|||
|
|
// ... onopen 中使用捕获的 token
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**状态**: ✅ 已修复并验证
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 🟡 Bug 4: SDKConfig 不支持自定义 baseUrl / wsUrl
|
|||
|
|
|
|||
|
|
**现象**: SDK 只能连接 `https://dev.xuqinmin.com`,无法切换到本地测试环境 `192.168.113.37`。
|
|||
|
|
**根因**: `init()` 硬编码使用 `DEFAULT_API_BASE_URL` 和 `DEFAULT_IM_WS_URL`,未从 `SDKConfig` 读取自定义 URL。
|
|||
|
|
|
|||
|
|
**修复**:
|
|||
|
|
- `SDKConfig` 类型添加 `baseUrl?: string` 和 `wsUrl?: string`
|
|||
|
|
- `init()` 使用 `config.baseUrl || DEFAULT_API_BASE_URL`
|
|||
|
|
- `ImClient.connect()` 使用 `config.wsUrl || DEFAULT_IM_WS_URL`
|
|||
|
|
|
|||
|
|
**状态**: ✅ 已修复并验证
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 🟡 Bug 5: 缺少 sendMessage / createGroup API 封装
|
|||
|
|
|
|||
|
|
**现象**: SDK 没有暴露 `sendMessage` 和 `createGroup` 函数,用户需直接调用 `http.post`。
|
|||
|
|
**根因**: `api.ts` 中缺少这两个常用 API 的封装。
|
|||
|
|
**修复**: 在 `src/im/api.ts` 中添加:
|
|||
|
|
```typescript
|
|||
|
|
export function sendMessage(params: {...}): Promise<ImMessage>
|
|||
|
|
export function createGroup(params: {...}): Promise<ImGroup>
|
|||
|
|
```
|
|||
|
|
并在 `src/index.ts` 中导出。
|
|||
|
|
|
|||
|
|
**状态**: ✅ 已修复并验证
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、测试详情
|
|||
|
|
|
|||
|
|
### 3.1 单元测试
|
|||
|
|
|
|||
|
|
| 模块 | 测试数 | 说明 |
|
|||
|
|
|------|--------|------|
|
|||
|
|
| core/sdk | 7 | init, getConfig, setToken, getToken, setUserId, getUserId |
|
|||
|
|
| core/http | 8 | configureHttp, buildUrl, GET/POST/PUT/DELETE, query 参数处理, Date 序列化, 错误处理 |
|
|||
|
|
| im/ImClient | 15 | STOMP 连接/发送/接收/撤回/重连/断开, 事件监听/取消, messageId 生成 |
|
|||
|
|
| im/useIm | 9 | Composable 状态管理, 消息增删改, 会话排序, 已读标记, 连接/断开 |
|
|||
|
|
|
|||
|
|
### 3.2 集成测试 (E2E)
|
|||
|
|
|
|||
|
|
| 模块 | 测试项 | 结果 |
|
|||
|
|
|------|--------|------|
|
|||
|
|
| Authentication | user_a / user_b 登录获取 token | ✅ |
|
|||
|
|
| SDK Initialization | 自定义 baseUrl/wsUrl | ✅ |
|
|||
|
|
| User Profile API | getProfile / updateProfile | ✅ |
|
|||
|
|
| Conversations API | listConversations / markRead | ✅ |
|
|||
|
|
| Message History API | fetchHistory / searchMessages | ✅ |
|
|||
|
|
| Friends API | listFriends / listFriendRequests / searchUsers | ✅ |
|
|||
|
|
| Groups API | listGroups / searchGroups / getGroupInfo | ✅ |
|
|||
|
|
| WebSocket Connection | 双端 STOMP 连接 | ✅ |
|
|||
|
|
| WebSocket Message Flow | send → history 确认 → sender echo → receiver push | ✅ |
|
|||
|
|
| Read Receipt | markRead HTTP + WS READ 状态推送 | ✅ |
|
|||
|
|
| Message Revoke | revoke WS + receiver revoke 事件 | ✅ |
|
|||
|
|
| Conversation Management | pin / mute / draft / delete | ✅ |
|
|||
|
|
| Group Operations | createGroup / fetchGroupHistory | ✅ |
|
|||
|
|
| Message Edit | editMessage | ✅ |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、Demo 应用
|
|||
|
|
|
|||
|
|
已创建独立 Vue3 Demo 应用:`/Users/xuqinmin/Projects/XuqmGroup/XuqmGroup-Vue3SDK-Demo/`
|
|||
|
|
|
|||
|
|
### 功能特性
|
|||
|
|
- 快捷登录(user_a / user_b / user_ascii)
|
|||
|
|
- WebSocket 实时连接状态显示
|
|||
|
|
- 会话列表(含未读角标)
|
|||
|
|
- 好友列表 / 群组列表
|
|||
|
|
- 实时聊天(发送/接收/撤回)
|
|||
|
|
- API 测试控制台(一键测试所有 API)
|
|||
|
|
- 操作日志面板
|
|||
|
|
|
|||
|
|
### 启动方式
|
|||
|
|
```bash
|
|||
|
|
cd /Users/xuqinmin/Projects/XuqmGroup/XuqmGroup-Vue3SDK-Demo
|
|||
|
|
npx vite
|
|||
|
|
# 访问 http://localhost:5173
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、代码变更清单
|
|||
|
|
|
|||
|
|
| 文件 | 变更类型 | 说明 |
|
|||
|
|
|------|----------|------|
|
|||
|
|
| `src/types/index.ts` | 修改 | SDKConfig 添加 baseUrl / wsUrl |
|
|||
|
|
| `src/core/sdk.ts` | 修改 | init() 支持自定义 baseUrl |
|
|||
|
|
| `src/im/ImClient.ts` | 重写 | 完整 STOMP 协议实现 |
|
|||
|
|
| `src/im/api.ts` | 修改 | 添加 sendMessage / createGroup |
|
|||
|
|
| `src/index.ts` | 修改 | 导出新增 API |
|
|||
|
|
| `package.json` | 修改 | 添加 test / test:watch / test:coverage 脚本 |
|
|||
|
|
| `vitest.config.ts` | 新增 | Vitest 测试配置 |
|
|||
|
|
| `__tests__/unit/core/sdk.test.ts` | 新增 | SDK 单元测试 |
|
|||
|
|
| `__tests__/unit/core/http.test.ts` | 新增 | HTTP 客户端单元测试 |
|
|||
|
|
| `__tests__/unit/im/ImClient.test.ts` | 新增 | ImClient 单元测试 |
|
|||
|
|
| `__tests__/unit/im/useIm.test.ts` | 新增 | useIm Composable 单元测试 |
|
|||
|
|
| `__tests__/integration/e2e.node.mjs` | 新增 | Node.js 端到端集成测试 |
|
|||
|
|
| `XuqmGroup-Vue3SDK-Demo/` | 新增 | Vue3 Demo 应用 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、服务端观察(非 SDK Bug)
|
|||
|
|
|
|||
|
|
在测试过程中,对服务端 `im-service` 的 `WebSocketConfig.java` 进行了代码审查:
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
String token = accessor.getFirstNativeHeader("Authorization");
|
|||
|
|
if (token != null && token.startsWith("Bearer ")) {
|
|||
|
|
token = token.substring(7);
|
|||
|
|
if (jwtUtil.isValid(token)) {
|
|||
|
|
String userId = jwtUtil.getSubject(token);
|
|||
|
|
...
|
|||
|
|
accessor.setUser(auth);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**观察**: 服务端仅从 STOMP header 读取 Authorization,不支持 URL query param `?token=xxx`。这是合理的设计(STOMP 规范推荐),但需在 SDK 文档中明确说明:**WebSocket 认证必须通过 CONNECT 帧的 `Authorization` header 传递**。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、下一步建议
|
|||
|
|
|
|||
|
|
1. **发布新版 SDK**: 当前修复包含重大协议变更(自定义 JSON → STOMP),建议发布新版本。
|
|||
|
|
2. **更新官方文档**: 在 README 中补充 `baseUrl` / `wsUrl` 配置说明。
|
|||
|
|
3. **Tenant Platform 集成**: 已在 tenant-platform 目录结构中找到 IM 管理页面,建议将 Vue3 SDK 集成到 `tenant-platform` 中作为管理员 IM 测试工具。
|
|||
|
|
4. **CI/CD 集成**: 将 `npm run test` 和 `node __tests__/integration/e2e.node.mjs` 纳入 Jenkins 流水线。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
> **测试结论**: Vue3 SDK 经过全面测试和修复,HTTP API 和 WebSocket 实时消息流均工作正常,所有 75 项测试通过。
|