@cg-devcenter/rtc-fpnn-webjs-sdk 1.0.0-cg.2 → 1.0.0-cg.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -43
- package/dist/rtm.d.ts +141 -2
- package/dist/rtm.min.js +6 -6
- package/dist/rtm.shared-worker.js +27 -0
- package/dist/rtm.vite.d.ts +12 -0
- package/dist/rtm.vite.mjs +24 -0
- package/docs/CAPABILITIES.md +124 -0
- package/docs/TLV.md +1 -1
- package/docs/TLV_CONTRACT.md +2 -2
- package/docs/TLV_LIVE_E2E_TEST.md +115 -0
- package/docs/USAGE.md +438 -160
- package/package.json +12 -7
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import rtm = require('./rtm');
|
|
2
|
+
|
|
3
|
+
declare const sdk: typeof rtm;
|
|
4
|
+
|
|
5
|
+
export default sdk;
|
|
6
|
+
export const RTMClient: typeof rtm.RTMClient;
|
|
7
|
+
export const RTMSharedWorkerClient: typeof rtm.RTMSharedWorkerClient;
|
|
8
|
+
export const RTMConfig: typeof rtm.RTMConfig;
|
|
9
|
+
export const RTMProcessor: typeof rtm.RTMProcessor;
|
|
10
|
+
export const TLVCodec: typeof rtm.TLVCodec;
|
|
11
|
+
export const TLVWebSocketClient: typeof rtm.TLVWebSocketClient;
|
|
12
|
+
export const createSharedWorkerName: typeof rtm.createSharedWorkerName;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import rtmModule from './rtm.min.js';
|
|
2
|
+
import workerUrl from './rtm.shared-worker.js?url';
|
|
3
|
+
|
|
4
|
+
const rtm = rtmModule.default || rtmModule;
|
|
5
|
+
|
|
6
|
+
class RTMSharedWorkerClient extends rtm.RTMSharedWorkerClient {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
const config = options || {};
|
|
9
|
+
super(Object.assign({}, config, {
|
|
10
|
+
workerUrl: config.workerUrl || workerUrl
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const sdk = Object.assign({}, rtm, { RTMSharedWorkerClient });
|
|
16
|
+
|
|
17
|
+
export const RTMClient = sdk.RTMClient;
|
|
18
|
+
export { RTMSharedWorkerClient };
|
|
19
|
+
export const RTMConfig = sdk.RTMConfig;
|
|
20
|
+
export const RTMProcessor = sdk.RTMProcessor;
|
|
21
|
+
export const TLVCodec = sdk.TLVCodec;
|
|
22
|
+
export const TLVWebSocketClient = sdk.TLVWebSocketClient;
|
|
23
|
+
export const createSharedWorkerName = sdk.createSharedWorkerName;
|
|
24
|
+
export default sdk;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# RTM WebSocket SDK 能力总览
|
|
2
|
+
|
|
3
|
+
本页按接入方的业务目标整理 SDK 能做什么、每项能力对应哪些 API,以及 TLV v1 与 FPNN 的使用入口。具体参数、回调字段和 wire body 以 [SDK API](USAGE.md) 与 [TLV v1 Client API 契约](TLV_CONTRACT.md) 为准;逐 API 的 TLV 支持状态以 [TLV v1 API 支持矩阵](USAGE.md#6-tlv-v1-api-支持矩阵) 为准。
|
|
4
|
+
|
|
5
|
+
下面的能力地图覆盖 SDK 整体 API;选择具体协议后,结合“协议与能力入口”表确定对应的调用入口和业务范围。
|
|
6
|
+
|
|
7
|
+
## 能力地图
|
|
8
|
+
|
|
9
|
+
| 业务目标 | SDK 能力 | 常用 API |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| 建立实时连接 | 登录、协议级关闭、主动关闭、自动重连、服务端时间、连接属性、调试日志 | `login`、`bye`、`close`、`startAutoReconnect`、`getServerTime`、`addAttrs`、`getAttrs`、`addDebugLog` |
|
|
12
|
+
| 同浏览器多窗口 | 同一 UID 共享一条 RTM WebSocket、共享登录态、按会话路由 Push | `RTMSharedWorkerClient`、`whenReady`、`loginIfNeeded`、`SharedSessionState`、`setConversation` |
|
|
13
|
+
| 维护用户状态 | 查询在线用户、设置/读取个人资料、读取公开资料、设置翻译语言 | `getOnlineUsers`、`setUserInfo`、`getUserInfo`、`getUserOpenInfo`、`setTranslationLanguage` |
|
|
14
|
+
| 保存用户数据 | 按 key 写入、读取和删除用户存储 | `dataSet`、`dataGet`、`dataDelete` |
|
|
15
|
+
| 用户关系控制 | 添加/解除黑名单并读取黑名单列表 | `addBlacks`、`deleteBlacks`、`getBlacks` |
|
|
16
|
+
| 一对一消息 | 发送文本、语音、命令消息;批量发送;接收可靠 Push | `sendChat`、`sendAudio`、`sendCmd`、`sendMessages`、`event.direct` |
|
|
17
|
+
| 群组消息 | 发送文本、语音、命令消息;接收群组 Push | `sendGroupChat`、`sendGroupAudio`、`sendGroupCmd`、`event.group` |
|
|
18
|
+
| 房间消息 | 进入/退出房间,发送文本、语音、命令消息,接收房间 Push | `enterRoom`、`leaveRoom`、`sendRoomChat`、`sendRoomAudio`、`sendRoomCmd`、`event.room` |
|
|
19
|
+
| 广播消息 | 接收广播 Push,查询广播历史和数量 | `event.broadcast`、`getBroadcastMessage`、`getBroadcastChat`、`getBroadcastMessageCount` |
|
|
20
|
+
| 群组管理 | 添加/移除成员,查询成员和人数,读取用户所在群组,设置和读取群组资料 | `addGroupMembers`、`deleteGroupMembers`、`getGroupMembers`、`getGroupCount`、`getUserGroups`、`setGroupInfo`、`getGroupInfo` |
|
|
21
|
+
| 房间管理 | 批量进入房间,查询房间成员/人数/资料,读取用户所在房间 | `enterRooms`、`getRoomMembers`、`getRoomCount`、`getUserRooms`、`setRoomInfo`、`getRoomInfo` |
|
|
22
|
+
| 历史消息 | 按时间和游标分页,按消息 ID 定位,统计消息数量 | `getP2PMessage`、`getGroupMessage`、`getRoomMessage`、`getBroadcastMessage`、`get*MessageByMessageId`、`get*MessageCount` |
|
|
23
|
+
| 单条消息管理 | 获取单条消息和撤回消息 | `getMessage`、`deleteMessage`、`getChat`、`deleteChat` |
|
|
24
|
+
| 收件箱同步 | 查询未读、清除未读、读取会话、标记会话已读、删除本地会话、读取会话列表 | `getUnreadMessage`、`cleanUnreadMessage`、`getSession`、`setSessionRead`、`removeSession`、`get*ConversationList` |
|
|
25
|
+
| 文本服务 | 文本审核、文本翻译、按用户设置翻译语言 | `textCheck`、`translate`、`setTranslationLanguage` |
|
|
26
|
+
| 文件消息 | 获取上传凭证和 endpoint,发送一对一/群组/房间文件 | `fileToken`、`sendFile`、`sendGroupFile`、`sendRoomFile` |
|
|
27
|
+
| 设备与好友 | 维护设备 Push 信息,维护好友关系 | `addDevice`、`removeDevice`、`getDevicePushOption`、`addFriends`、`deleteFriends`、`getFriends` |
|
|
28
|
+
| 多媒体内容服务 | 敏感词处理、图片/音频/视频审核、语音转文字 | `profanity`、`imageCheck`、`audioCheck`、`videoCheck`、`speech2Text` |
|
|
29
|
+
|
|
30
|
+
## 协议与能力入口
|
|
31
|
+
|
|
32
|
+
| 入口 | 适合场景 | 主要能力 |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| `protocol: 'tlv-v1'` | 新项目、浏览器和 Node.js 接入 | 连接鉴权、用户与存储、黑名单、用户/群组/房间/广播消息、可靠 Push、历史、未读、会话、文本审核、翻译。 |
|
|
35
|
+
| `protocol: 'fpnn'` | 现有浏览器 RTM 应用的兼容接入 | 兼容 SDK 的完整传统 API 族,包括文件、设备、好友和多媒体内容服务。 |
|
|
36
|
+
|
|
37
|
+
### 协议与运行边界
|
|
38
|
+
|
|
39
|
+
| 能力 | `RTMClient` + TLV v1 | `RTMClient` + FPNN | `RTMSharedWorkerClient` |
|
|
40
|
+
| --- | --- | --- | --- |
|
|
41
|
+
| 连接环境 | 浏览器;Node.js 需传入 `webSocketFactory` | 浏览器 | 支持 SharedWorker 的浏览器,同源页面 |
|
|
42
|
+
| 用户/群组/房间/广播消息 | 支持;按 TLV v1 契约字段校验 | 支持兼容 API | 支持 TLV 已开放 API |
|
|
43
|
+
| Push ACK 与去重 | SDK 自动 ACK 可靠 Push,并按 `message_ref` 去重 | 沿用兼容实现 | 单条共享连接只 ACK 一次,再按页面会话路由给各端口 |
|
|
44
|
+
| 文件、设备、好友、多媒体审核 | TLV v1 当前未开放的传统 API 不可用 | 兼容 API 可用,依赖对应服务端能力 | 文件发送明确不支持;其余能力以 TLV v1 支持范围为准 |
|
|
45
|
+
| 多页面连接共享 | 每个 `RTMClient` 实例各自管理连接 | 每个 `RTMClient` 实例各自管理连接 | 相同 Worker identity 与配置下,同一 UID 共用一条连接 |
|
|
46
|
+
| 业务 UI 与消息存储 | 应用负责展示、缓存和历史补拉 | 应用负责展示、缓存和历史补拉 | 只路由实时 Push;不跨页同步草稿、未读 UI 状态或本地消息列表,也不持久化消息 |
|
|
47
|
+
|
|
48
|
+
TLV v1 的能力以 [Client API 契约](TLV_CONTRACT.md) 的 URI 表为准;旧 API 名称存在不代表 TLV 服务端开放了该 wire。保留但未开放的 wire 返回 `200020`(`RTM_EC_FORBIDDEN_METHOD`);未知且未登记的 wire 返回 `20004`(`RTM_EC_UNKNOWN_METHOD`)。`RTMSharedWorkerClient` 的文件发送方法在本地拒绝:callback 收到 `{mid, error}`,Promise 版本 reject 同一对象,`error.code` 为 `200999`(`RTM_EC_UNKNOWN_ERROR`),不发送 wire 请求。以上情况均不会退回 FPNN。SharedWorker 不是另一套 RTC 协议,也不替业务服务端签发 credential。
|
|
49
|
+
|
|
50
|
+
### SharedWorker 共享范围
|
|
51
|
+
|
|
52
|
+
- SDK 会默认从加载它的页面脚本同目录定位 `rtm.shared-worker.js`;Vite 项目可从 `@cg-devcenter/rtc-fpnn-webjs-sdk/vite` 导入 ESM 入口,由 SDK 自动将 Worker 作为构建资源配置给客户端。部署时 Worker 必须在页面同源下可访问;非 Vite 自定义部署路径时可显式提供 `workerUrl`。
|
|
53
|
+
- 共享键由浏览器 origin、Worker URL、Worker 名称和完全相同的 `clientOptions` 共同决定;这些值不同的页面不会共用连接。
|
|
54
|
+
- 一个 Worker 只登录一个 UID。不同 UID 同时在线必须分别建立 Worker/RTC 连接;单 UID 的多页面共享登录态。
|
|
55
|
+
- 每个页面有独立的 Push 监听端口。配置 `conversation` 后,SDK 按 direct sender、group ref 或 room ref 过滤;未配置时该页面接收全部会话 Push。
|
|
56
|
+
- SDK 负责连接、重连、Push ACK/去重和端口分发;业务仍负责消息展示、历史补拉、业务未读规则、草稿与页面状态。
|
|
57
|
+
- 登录态保存在 Worker 内存。Worker 被浏览器回收或空闲回收完成后,需要业务重新创建 client 并登录;SDK 不持久化 credential,也不承诺把断线期间未投递的 Push 自动补齐。
|
|
58
|
+
- `destroy()` 只 detach 当前页面;最后一个页面 detach 后默认等待 5 秒再销毁共享 RTMClient,期间有新页面接入会取消回收。可通过 `idleShutdownTimeout` 调整,设为 0 表示立即关闭;同一个 Worker 的页面须使用相同值。`bye()` / `close()` 会结束所有共用页面的 RTC 会话。共享 Worker 初始化失败时不会静默降级为每页单独连接。
|
|
59
|
+
|
|
60
|
+
TLV v1 使用 MessagePack 二进制 WebSocket frame。SDK 提供以下基础模块:
|
|
61
|
+
|
|
62
|
+
- `RTMClient`:面向业务的登录、消息、群组、房间、历史和会话 API。
|
|
63
|
+
- `RTMProcessor`:接收并分发 Push;通过 `client.processor.on(name, callback)` 订阅事件。
|
|
64
|
+
- `TLVCodec`:编解码 TLV frame、Answer、Push 和 MessagePack body。
|
|
65
|
+
- `TLVWebSocketClient`:管理 TLV WebSocket 请求、响应、心跳和连接状态。
|
|
66
|
+
- `RTMConfig`:提供 `Int64`、消息类型、文件类型和 Push 名称常量。
|
|
67
|
+
|
|
68
|
+
## 典型业务流程
|
|
69
|
+
|
|
70
|
+
### Callback 与 Promise 写法
|
|
71
|
+
|
|
72
|
+
为兼容既有应用,`RTMClient` 和 `RTMSharedWorkerClient` 保留 callback 方法;两者也提供 `client.promises`,把所有 callback 型业务请求封装为 Promise。原方法参数顺序不变,只省略 callback:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
const result = await client.promises.sendChat(peerUid, 'hello', '{}', 0, 12000);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`client.promises.login(uid, credential, timeout?)` 成功时 resolve `{ accepted: true, errorCode }`,鉴权失败时 reject 一个带 `code` 的 Error。TLV Gate 返回 `control.error` 时保留服务端错误码;若只返回 `accepted: false`,SDK 使用 `200027`。`client.promises.bye(timeout?)` 等待 Gate 应答协议关闭;TLV 请求失败时 SDK 主动关闭连接。`RTMSharedWorkerClient.loginIfNeeded()` 保持自己的结果约定:RTC 鉴权结果 resolve 为 `{ accepted, errorCode, reused, uid }`;Worker 初始化错误及缺少首次登录 credential 会 reject。其他生命周期方法和事件仍通过 client 本身调用。
|
|
79
|
+
|
|
80
|
+
### 一对一聊天
|
|
81
|
+
|
|
82
|
+
1. 构造 `RTMClient`,注册 `ErrorRecorder` 和 `event.direct` Push 监听。
|
|
83
|
+
2. 调用 `login` 进入登录态。
|
|
84
|
+
3. 使用 `sendChat`、`sendAudio` 或 `sendCmd` 发送消息。
|
|
85
|
+
4. 在 `event.direct` 回调中接收对方消息;SDK 自动回复可靠 Push 的 `control.ack` 并按 `message_ref` 去重。
|
|
86
|
+
5. 使用 `getP2PMessage` 或 `getP2PConversationList` 加载历史和会话摘要。
|
|
87
|
+
|
|
88
|
+
### 群组与房间互动
|
|
89
|
+
|
|
90
|
+
群组流程使用 `addGroupMembers`、`getGroupMembers` 和 `sendGroupChat` 管理成员与消息;房间流程使用 `enterRoom`、`getRoomMembers` 和 `sendRoomChat` 管理在线参与者与消息。两类消息分别通过 `event.group` 和 `event.room` 接收。
|
|
91
|
+
|
|
92
|
+
### 登录后的收件箱同步
|
|
93
|
+
|
|
94
|
+
应用恢复到前台或完成重新登录后,可以组合使用:
|
|
95
|
+
|
|
96
|
+
1. `getUnreadMessage` 获取未读范围;
|
|
97
|
+
2. `getP2PUnreadConversationList`、`getGroupUnreadConversationList` 或 `getUnreadConversationList` 获取会话摘要;
|
|
98
|
+
3. `getP2PMessage`、`getGroupMessage` 或 `getRoomMessage` 分页读取历史;
|
|
99
|
+
4. `setSessionRead` 标记已读,必要时使用 `cleanUnreadMessage` 清理全局未读状态。
|
|
100
|
+
|
|
101
|
+
### 发送前的内容处理
|
|
102
|
+
|
|
103
|
+
发送文本前可先调用 `textCheck` 获取审核结果,再根据业务策略调用 `translate` 生成目标语言内容,最后使用 `sendChat`、`sendGroupChat` 或 `sendRoomChat` 发送。审核和翻译的请求字段、返回结构见 [TLV v1 Client API 契约](TLV_CONTRACT.md)。
|
|
104
|
+
|
|
105
|
+
### 文件消息
|
|
106
|
+
|
|
107
|
+
文件消息可以使用 `fileToken` 获取上传所需的 token 和 endpoint,再调用 `sendFile`、`sendGroupFile` 或 `sendRoomFile` 完成消息发送;接收方通过对应的文件 Push 获取文件地址和消息元数据。
|
|
108
|
+
|
|
109
|
+
## 核心数据约定
|
|
110
|
+
|
|
111
|
+
- **ID 与时间**:用户 ID、群组 ID、房间 ID、消息引用和时间游标可能超过 JavaScript 安全整数范围,使用 `new RTMConfig.Int64(String(value))` 传入和读取。
|
|
112
|
+
- **消息类型**:`RTMConfig.CHAT_TYPE.text`、`audio`、`cmd` 分别对应文本、语音和命令消息。
|
|
113
|
+
- **文件类型**:文件消息的类型使用 `RTMConfig.FILE_TYPE` 中的 image、audio、video、file。
|
|
114
|
+
- **普通回调**:大多数业务 API 使用 `callback(err, data)`;发送 API 成功结果包含 `message_ref` 和 `payload`。
|
|
115
|
+
- **登录回调**:`login` 使用 `callback(accepted, errorCode)`;连接、协议和登录错误可通过 `ErrorRecorder` 观察。普通业务 API 的 Gate 错误由对应的 `callback(err, data)` 或 Promise rejection 返回,不会另发全局事件。
|
|
116
|
+
- **TLV Push**:应用通过 `RTMConfig.TLV_SERVER_PUSH` 取得 `event.direct`、`event.group`、`event.room`、`event.broadcast`、`event.kicked` 和 `event.room_removed` 的订阅名称。
|
|
117
|
+
|
|
118
|
+
## 文档导航
|
|
119
|
+
|
|
120
|
+
- [快速开始与引用](../README.md)
|
|
121
|
+
- [公开 API 参数](USAGE.md)
|
|
122
|
+
- [TLV v1 URI、字段和返回值](TLV_CONTRACT.md)
|
|
123
|
+
- [TLV v1 frame 与编解码](TLV.md)
|
|
124
|
+
- [在线验证与业务套件](TLV_LIVE_E2E_TEST.md)
|
package/docs/TLV.md
CHANGED
|
@@ -42,7 +42,7 @@ TLV v1 使用 MessagePack over WebSocket。公开方法见 [SDK API](USAGE.md)
|
|
|
42
42
|
|
|
43
43
|
| URI | 请求/响应 body | 行为 |
|
|
44
44
|
| --- | --- | --- |
|
|
45
|
-
| `control.ping` | `{}` / `{}` | SDK
|
|
45
|
+
| `control.ping` | `{}` / `{ts?:int64}` | SDK 空闲心跳;Gate 可在 Answer 中返回时间戳。 |
|
|
46
46
|
| `control.ack` | `{}` | 复用可靠 Push sequence;无需应答。 |
|
|
47
47
|
| `control.error` | `{status:int32, reason:string}` | Gate 请求失败应答。 |
|
|
48
48
|
| `connection.close` | `{}` / `{}` | Gate 应答后关闭连接。 |
|
package/docs/TLV_CONTRACT.md
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
| URI | `mt` | body |
|
|
26
26
|
| --- | --- | --- |
|
|
27
|
-
| `control.ping` | `'1'` / `'2'` | `{}` |
|
|
27
|
+
| `control.ping` | `'1'` / `'2'` | request `{}`; Answer `{ts?:i64}` |
|
|
28
28
|
| `control.ack` | `'2'` | `{}` |
|
|
29
29
|
| `control.error` | `'2'` | `{status:i32, reason:str}` |
|
|
30
30
|
| `event.direct` | `'1'` | `recipient, sender, message_ref, kind, payload, extra, time_ms` |
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
|
|
42
42
|
| SDK API | Gate URI | 请求字段 | Gate Answer |
|
|
43
43
|
| --- | --- | --- | --- |
|
|
44
|
-
| `login` | `auth.login` | `project, user, credential, client_ver, auth_sec?, auth_ver?, locale?, props?` | `accepted
|
|
44
|
+
| `login` | `auth.login` | `project, user, credential, client_ver, auth_sec?, auth_ver?, locale?, props?` | `accepted, telemetry_on?` |
|
|
45
45
|
| `bye` | `connection.close` | 无 | 无 |
|
|
46
46
|
| `getServerTime` | `system.time` | 无 | `server_ms` |
|
|
47
47
|
| `addAttrs` | `connection.set_props` | `props` | 无 |
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# TLV v1 在线验证页面
|
|
2
|
+
|
|
3
|
+
验证页面位于 `test/e2e/live-tlv-suite.html`。它用于验证一个真实 TLV Gate 环境与 SDK 的联调结果,不替代本地协议测试或 npm 包 smoke test。页面只接受运行时输入,不内置环境参数、项目密钥或 credential。
|
|
4
|
+
|
|
5
|
+
## 前置条件
|
|
6
|
+
|
|
7
|
+
- 能访问目标 TLV WebSocket endpoint,并准备好对应的 RTC `pid`。
|
|
8
|
+
- 准备两个不同的、正整数 UID,以及服务端签发给这两个 UID 的有效 credential。
|
|
9
|
+
- 如需验证群组流程,准备一个已存在且 UID A 有成员管理权限的 Group ID。
|
|
10
|
+
- 如需把黑名单、文本审核和翻译作为强制能力验证,勾选页面上的“要求黑名单、文本审核和翻译能力通过”。
|
|
11
|
+
- 浏览器需要支持 WebSocket、`TextEncoder` 和 `TextDecoder`。
|
|
12
|
+
|
|
13
|
+
credential 应从服务端鉴权流程取得,不要把项目密钥放进浏览器页面、URL 或 `requestMetadata`。
|
|
14
|
+
|
|
15
|
+
## 启动页面
|
|
16
|
+
|
|
17
|
+
页面通过相对路径加载仓库内的 `dist/rtm.min.js`,所以应从仓库根目录启动 HTTP 服务,不能直接使用 `file://` 打开:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cd ~/Documents/code/origin/rtm-client-sdk-websocket
|
|
21
|
+
|
|
22
|
+
# 只有在 dist 需要由当前源码重新生成时才执行;依赖未安装时先执行 npm install
|
|
23
|
+
npm install
|
|
24
|
+
npm run build
|
|
25
|
+
|
|
26
|
+
python3 -m http.server 8000
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
然后打开:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
http://127.0.0.1:8000/test/e2e/live-tlv-suite.html
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
如果只是验证仓库当前已提交的 `dist`,可以跳过 `npm install` 和 `npm run build`,直接启动 HTTP 服务。若页面提示 `rtm` 未定义或脚本加载失败,先确认服务根目录是本仓库,而不是 `test/e2e` 目录。
|
|
36
|
+
|
|
37
|
+
## 执行顺序
|
|
38
|
+
|
|
39
|
+
推荐先执行仓库内的本地检查,再执行在线页面:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm run test:unit # TLV 协议与文档链接/覆盖检查
|
|
43
|
+
npm run test:package # 重新构建 dist,并验证 CommonJS 与浏览器 UMD 包入口
|
|
44
|
+
npm test # 以上两组检查的合并入口
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
在线页面按以下顺序运行:
|
|
48
|
+
|
|
49
|
+
1. 点击“运行无凭证 `control.ping`”,确认 WebSocket、TLV frame header、Answer sequence,以及请求空 map 和应答 `{}` / `{ts}` 均正确。
|
|
50
|
+
2. 填写 endpoint、pid、两个 UID 和 credential,点击“运行业务覆盖套件”。
|
|
51
|
+
3. 页面先执行两个 `auth.login`,再执行系统、用户、存储、黑名单、群组、房间、消息、历史、未读、会话、重连和关闭流程。
|
|
52
|
+
4. 页面会清理本次运行写入的存储、黑名单、房间和群成员状态;仍建议使用专用测试账号和测试群组。
|
|
53
|
+
|
|
54
|
+
## 输入
|
|
55
|
+
|
|
56
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
57
|
+
| --- | --- | --- | --- |
|
|
58
|
+
| `endpoint` | `string` | 是 | TLV WebSocket URL。 |
|
|
59
|
+
| `pid` | `number` | 是 | RTC 项目 ID。 |
|
|
60
|
+
| `uidA` / `credentialA` | `string` | 是 | 第一个 Client 身份;UID 必须是正整数。 |
|
|
61
|
+
| `uidB` / `credentialB` | `string` | 是 | 第二个 Client 身份;必须与 A 不同。 |
|
|
62
|
+
| `groupId` | `string` | 否 | 已配置的群组 ID;填写时 UID A 必须有相应权限。 |
|
|
63
|
+
| `requireCapabilities` | `boolean` | 否 | 要求黑名单、审核、翻译 API 通过;未勾选时这些外部能力可以 `SKIP`。 |
|
|
64
|
+
|
|
65
|
+
## 覆盖范围
|
|
66
|
+
|
|
67
|
+
| 阶段 | 动作 | 协议/API 范围 |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| P0 | `control.ping` | 无凭证 TLV frame、Answer sequence、请求空 map 和应答 `{}` / `{ts}`。 |
|
|
70
|
+
| A1 | 登录与连接 | `auth.login`、连接属性、`system.time`、自动重连与 `connection.close`。 |
|
|
71
|
+
| U1/B1 | 用户与基础数据 | 在线状态、用户资料、公开资料、语言、存储和黑名单。 |
|
|
72
|
+
| G1/R1 | 群组与房间 | 群组成员/资料/计数、房间加入/退出/成员/资料。配置缺失时群组流程会跳过。 |
|
|
73
|
+
| M1/M2 | 消息与 Push | 单发、批量、群组/房间消息、`event.direct`/`event.group`/`event.room`、ACK 与去重。 |
|
|
74
|
+
| H1/H2/S1 | 读取与会话 | 历史消息、计数、撤回、未读、Session 和 Conversation。 |
|
|
75
|
+
| X1/N1 | 能力与负向契约 | 黑名单能力、文本审核、翻译,以及保留 friend wire 的 `200020` 拒绝。 |
|
|
76
|
+
|
|
77
|
+
可靠 Push 会自动回复 `control.ack`;套件还会检查同一 `message_ref` 不被重复投递。页面使用带时间戳的 marker 写入测试数据,便于从结果中定位本次运行。
|
|
78
|
+
|
|
79
|
+
## 结果判定
|
|
80
|
+
|
|
81
|
+
| 状态 | 含义 |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| `PASS` | 接口返回、响应字段和协议校验符合契约。 |
|
|
84
|
+
| `FAIL` | 接口调用、响应、Push、协议或超时校验不符合预期;应先看该行错误码和浏览器控制台。 |
|
|
85
|
+
| `SKIP` | 可选群组未配置,或未勾选强制能力时服务没有开放相应外部能力。 |
|
|
86
|
+
|
|
87
|
+
未勾选强制能力时,页面允许以下环境差异产生 `SKIP`:
|
|
88
|
+
|
|
89
|
+
- 黑名单:`200060`。
|
|
90
|
+
- 文本审核或翻译:`200020` 或 `300001`。
|
|
91
|
+
- 未填写 `groupId` 时,群组相关覆盖也会明确标记为 `SKIP`。
|
|
92
|
+
|
|
93
|
+
勾选强制能力后,上述错误会变成 `FAIL`,用于验证目标环境是否真的提供这些能力。`N1 reserved friend wire` 预期收到 `200020`,它是负向协议检查,不是故障。
|
|
94
|
+
|
|
95
|
+
## 排障路径
|
|
96
|
+
|
|
97
|
+
| 现象 | 优先检查 |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| 页面空白、`rtm` 未定义或脚本 404 | 是否从仓库根目录运行 HTTP 服务;`dist/rtm.min.js` 是否存在;源码有改动时是否重新执行 `npm run build`。 |
|
|
100
|
+
| WebSocket error、`control.ping` 失败或超时 | endpoint 的 scheme/路径、TLS 或反向代理、浏览器网络连通性;在 DevTools 的 Network → WS 查看握手和二进制帧,在 Console 查看协议断开原因。 |
|
|
101
|
+
| `200022` | 请求在登录完成前发送,或连接鉴权状态已失效。先确认 `auth.login` 成功。 |
|
|
102
|
+
| `200024` / `200027` | credential 被拒绝、过期或与 pid/UID 不匹配;重新从服务端获取,不要在页面输出 credential。 |
|
|
103
|
+
| `200020` / `200021` | URI 未开放或权限不足;确认 TLV 能力开关、项目权限和测试账号角色。 |
|
|
104
|
+
| `200034`、`200030` | 字段名/类型/范围或 payload/extra 大小不符合契约;对照 [TLV v1 传输 API](TLV.md) 和 [TLV v1 Client API 契约](TLV_CONTRACT.md)。 |
|
|
105
|
+
| `200053` | `message_ref` 重复;确认测试 marker、重试策略和业务侧 message_ref 生成规则。 |
|
|
106
|
+
| `200999` | 连接、超时或服务端内部错误;结合 `ErrorRecorder`、`SessionClosed` 和浏览器 Network 日志判断发生阶段。 |
|
|
107
|
+
|
|
108
|
+
SDK 调试时可重点观察:
|
|
109
|
+
|
|
110
|
+
- `ErrorRecorder`:查看连接、协议和登录层的 `code/status/reason`,比 `login` 的布尔结果更适合定位环境问题;普通业务请求的 Gate 错误要检查对应 callback 或 Promise rejection。
|
|
111
|
+
- `ReloginCompleted`、`SessionClosed`:判断自动重连是成功、失败还是被服务端关闭。
|
|
112
|
+
- `requestMetadata`:为每个请求附加不含秘密的 `trace` 和 `sent_ms`,用于和 Gate 日志关联。
|
|
113
|
+
- 原始 URI、字段和 frame 编解码问题:对照 [TLV v1 传输 API](TLV.md) 与 [TLV v1 Client API 契约](TLV_CONTRACT.md)。
|
|
114
|
+
|
|
115
|
+
页面会尽量脱敏结果,不保存 UID、credential、项目密钥或运行结果;仍不要把结果页截图或浏览器 Network 导出直接发到公开渠道。
|