test: add websocket protocol audit

This commit is contained in:
richjohnrambo
2026-08-21 00:42:54 +08:00
parent ff616b9c5d
commit 14abe58b88
5 changed files with 1122 additions and 3 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,58 @@
# IM WebSocket 测试环境专项联调结果(2026-08-21)
## 1. 测试范围
- 测试时间:`2026-08-21 00:39:01 +0800`
- HTTP:`https://api.118im.com`
- WebSocket:`wss://api.118im.com/v0/channels`
- 租户:`default`
- 用户 A:`usr7-zA3UMrw7c` / `wsa459000` / `15794459000`
- 用户 B:`usrnDXQ3A2oQP0` / `wsb459000` / `15894459000`
- API Key 与 Token 已脱敏,不在文档中展开。
## 2. 总体结论
本轮专项验证 Tinode WebSocket 真实协议链路,共执行 `29` 项,通过 `27` 项,未通过 `2` 项。
| ID | 场景 | 方法 | 目标 | 结果 | 备注 |
| --- | --- | --- | --- | --- | --- |
| `WS-01` | 注册用户 A: HTTP 验证码 + WS acc | `WS` | `/v0/channels` | 通过 | user=usr7-zA3UMrw7c token=AwEA...18Om |
| `WS-02` | 注册用户 B: HTTP 验证码 + WS acc | `WS` | `/v0/channels` | 通过 | user=usrnDXQ3A2oQP0 token=AwEA...NX6b |
| `WS-03` | HTTP 建立好友关系生成 P2P Topic | `HTTP` | `/v1/im/friend-requests` | 通过 | request_id=frq_KAOkEfarCOA topic=p2p7-zA3UMrw7ecNdDcDahA_Q |
| `WS-04` | A token login + sub me | `WS` | `/v0/channels` | 通过 | login user=usr7-zA3UMrw7c |
| `WS-05` | B token login + sub me | `WS` | `/v0/channels` | 通过 | login user=usrnDXQ3A2oQP0 |
| `WS-06` | A/B 订阅 P2P Topic | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 通过 | topic=p2p7-zA3UMrw7ecNdDcDahA_Q |
| `WS-07` | A pub 文本消息,B 收到 data | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 通过 | seq=1 bob_topic=usr7-zA3UMrw7c |
| `WS-08` | B 发送 recv/read 回执 | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 通过 | what=read seq=1 |
| `WS-09` | basic login + sub me | `WS` | `/v0/channels` | 通过 | basic login ok |
| `WS-10` | 重复 login 被拒绝 | `WS` | `/v0/channels` | 通过 | code=409 text=already authenticated |
| `WS-11` | 订阅 fnd 搜索 Topic | `WS` | `fnd` | 通过 | sub fnd ok |
| `WS-12` | get me desc/sub/tags/cred | `WS` | `me` | 通过 | get me ok |
| `WS-13` | get P2P desc/sub/data/del | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 通过 | get p2p ok |
| `WS-14` | set P2P private 设置 | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 通过 | set private ok |
| `WS-15` | pub 产品 x-im 基础头 | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 通过 | seq=2 bob_topic=usr7-zA3UMrw7c |
| `WS-16` | pub 产品 x-im-client-mid 幂等头 | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 未通过 | pub ctrl: ctrl id=pub-003857.244320000 code=500 text=internal error |
| `WS-17` | note kp 输入中通知 | `WS` | `usr7-zA3UMrw7c` | 通过 | what=kp |
| `WS-18` | del 当前用户消息视图 | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 通过 | deleted seq=1 |
| `WS-19` | leave P2P detach 后重新订阅 | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 通过 | leave/resub ok |
| `WS-20` | HTTP 创建群供 WS 群协议测试 | `HTTP` | `/v1/im/groups` | 通过 | topic=grpURzKYanXB1Y |
| `WS-21` | A/B 订阅群 Topic | `WS` | `grpURzKYanXB1Y` | 通过 | sub group ok |
| `WS-22` | 群 pub 文本广播 | `WS` | `grpURzKYanXB1Y` | 通过 | seq=1 topic=grpURzKYanXB1Y |
| `WS-23` | get 群 desc/sub/data | `WS` | `grpURzKYanXB1Y` | 通过 | get group ok |
| `WS-24` | 文件上传 /v0/file/u | `HTTP` | `/v0/file/u/` | 通过 | url=/v0/....bin |
| `WS-25` | WS 文件消息下发 | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 通过 | seq=3 bob_topic=usr7-zA3UMrw7c |
| `WS-26` | WebRTC 通话 invite pub | `WS` | `p2p7-zA3UMrw7ecNdDcDahA_Q` | 未通过 | pub ctrl: ctrl id=pub-003859.867810000 code=501 text=not implemented |
| `WS-27` | 未 hi 直接 login 被拒绝 | `WS` | `/v0/channels` | 通过 | code=409 text=command out of sequence |
| `WS-28` | hi 后切换 tenant 被拒绝 | `WS` | `/v0/channels` | 通过 | code=409 text=command out of sequence |
| `WS-29` | 非法 API Key 拒绝建连 | `WS` | `/v0/channels` | 通过 | http_status=403 |
## 3. 覆盖说明
- 已覆盖:API Key Upgrade、`hi(tenant)`、`acc`、`basic login`、`token login`、重复登录拒绝、`sub me/fnd/p2p/grp`、`get desc/sub/data/del/tags/cred`、`set sub.private`、P2P/群 `pub`、产品 `x-im-*` 基础头、`note recv/read/kp`、`del msg`、`leave`、文件上传入口、文件消息、WebRTC invite、未 hi 顺序错误、切换租户拒绝、非法 API Key 拒绝。
- 仍需前端/真机补充:断线重连恢复、Long Polling 长轮询持续收包、真实音视频媒体协商质量、离线 Push 到达与点击恢复。
## 4. 测试产生的数据
- P2P Topic:`p2p7-zA3UMrw7ecNdDcDahA_Q`
- Bob 收到的 Topic:`usr7-zA3UMrw7c`
- 消息 Seq:`1`
+3 -2
View File
@@ -3568,10 +3568,11 @@ func (a *adapter) MessageSave(msg *t.Message) error {
}
// store assignes message ID, but we don't use it. Message IDs are not used anywhere.
// Using a sequential ID provided by the database.
clientMsgID := sql.NullString{String: msg.ClientMsgID, Valid: msg.ClientMsgID != ""}
res, err := a.db.ExecContext(ctx,
"INSERT INTO im_messages(createdAt,updatedAt,seqid,topic,`from`,head,content) VALUES(?,?,?,?,?,?,?)",
"INSERT INTO im_messages(createdAt,updatedAt,seqid,topic,`from`,client_msg_id,version,head,content) VALUES(?,?,?,?,?,?,?,?,?)",
msg.CreatedAt, msg.UpdatedAt, msg.SeqId, msg.Topic,
store.DecodeUid(t.ParseUid(msg.From)), msg.Head, common.ToJSON(msg.Content))
store.DecodeUid(t.ParseUid(msg.From)), clientMsgID, messageVersion(msg.Version), msg.Head, common.ToJSON(msg.Content))
if err == nil {
id, _ := res.LastInsertId()
// Replacing ID given by store by ID given by the DB.
+1 -1
View File
@@ -1622,7 +1622,7 @@ func (a *adapter) TenantMessageSave(id t.TenantID, msg *t.Message) error {
return t.ErrMalformed
}
if tenantAdp != a {
return tenantAdp.MessageSave(msg)
return tenantAdp.TenantMessageSave(id, msg)
}
if a.tenantScopedDB {
return a.MessageSave(msg)
+10
View File
@@ -36,6 +36,16 @@
}
},
"webrtc": {
"enabled": true,
"call_establishment_timeout": 30,
"ice_servers": [
{
"urls": ["stun:stun.l.google.com:19302"]
}
]
},
"tls": {
"enabled": false,
"http_redirect": "",