feat: add realtime challenge client and local smoke test
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
# 本地实时 1v1 与联机码约战测试
|
||||
|
||||
本指南用于在一台电脑上使用两个浏览器会话验证完整联机流程。
|
||||
|
||||
## 1. 准备数据
|
||||
|
||||
```bash
|
||||
make install
|
||||
make migrate
|
||||
make seed
|
||||
```
|
||||
|
||||
种子数据会创建三个赛道的实时 1v1 比赛。本地邀请码为:
|
||||
|
||||
```text
|
||||
HULU2026
|
||||
```
|
||||
|
||||
## 2. 使用 ASGI 启动
|
||||
|
||||
实时比赛依赖 WebSocket。不要使用普通 WSGI 服务测试联机。
|
||||
|
||||
```bash
|
||||
make run-asgi
|
||||
```
|
||||
|
||||
访问:
|
||||
|
||||
```text
|
||||
http://127.0.0.1:8000/
|
||||
```
|
||||
|
||||
本地没有配置 `REDIS_URL` 时会使用进程内 Channel Layer,适合单进程开发测试。生产环境必须使用 Redis。
|
||||
|
||||
### 一键端到端验证
|
||||
|
||||
保持 `make run-asgi` 运行,另开终端执行:
|
||||
|
||||
```bash
|
||||
.venv/bin/python scripts/test_realtime_local.py
|
||||
```
|
||||
|
||||
脚本会临时创建两个本地账号,通过真实 HTTP Session 和两个真实 WebSocket 完成:
|
||||
|
||||
```text
|
||||
创建联机码
|
||||
→ 第二位玩家加入
|
||||
→ matched 状态推送
|
||||
→ 答题进度同步
|
||||
→ 第一位提交且不泄露答案
|
||||
→ 第二位提交
|
||||
→ completed 推送
|
||||
→ 胜负、Rating 和解析检查
|
||||
```
|
||||
|
||||
结束后脚本自动清理临时用户和比赛记录。
|
||||
|
||||
## 3. 准备两个独立登录会话
|
||||
|
||||
使用下列任一组合:
|
||||
|
||||
- Chrome 普通窗口 + 无痕窗口
|
||||
- Chrome + Safari
|
||||
- 两个不同浏览器 Profile
|
||||
|
||||
两个窗口分别使用邀请码 `HULU2026` 注册不同账号。不要在同一浏览器 Profile 的两个普通标签页登录不同账号,因为它们会共享 Session Cookie。
|
||||
|
||||
## 4. 联机码约战
|
||||
|
||||
玩家 A:
|
||||
|
||||
1. 打开“比赛”。
|
||||
2. 选择双方约定的赛道。
|
||||
3. 点击“创建当前赛道约战”。
|
||||
4. 复制 6 位联机码。
|
||||
|
||||
玩家 B:
|
||||
|
||||
1. 打开“比赛”。
|
||||
2. 输入联机码。
|
||||
3. 点击“加入约战”。
|
||||
|
||||
预期结果:
|
||||
|
||||
- 玩家 A 无需再次点击,自动进入答题。
|
||||
- 双方显示相同题目和同一个倒计时。
|
||||
- 任一方填写答案时,另一方看到答题数量变化。
|
||||
- 第一位提交者只看到“答案已锁定”,看不到正确答案。
|
||||
- 双方提交或倒计时结束后,同时展示胜负、双方分数、Rating 变化和题目解析。
|
||||
|
||||
## 5. 随机匹配
|
||||
|
||||
双方选择同一赛道并点击“开始匹配”。
|
||||
|
||||
预期结果:
|
||||
|
||||
- 第一位玩家进入等待状态。
|
||||
- 第二位玩家加入后,第一位玩家自动进入答题。
|
||||
- 私人联机码房间不会被随机匹配玩家加入。
|
||||
|
||||
## 6. 断线与超时
|
||||
|
||||
验证以下场景:
|
||||
|
||||
1. 答题时短暂关闭网络,再恢复。
|
||||
2. WebSocket 断开后页面仍每 2 秒轮询比赛状态。
|
||||
3. 关闭其中一个窗口,另一方等待倒计时结束。
|
||||
4. 服务端到时后将未提交 Attempt 标记为过期并完成结算。
|
||||
5. 等待中的联机码 10 分钟后失效。
|
||||
|
||||
## 7. 排查
|
||||
|
||||
浏览器开发者工具应看到:
|
||||
|
||||
```text
|
||||
WS /ws/v1/contest/matches/<match_id>/
|
||||
GET /api/v1/contests/matches/<match_id>/
|
||||
```
|
||||
|
||||
检查 Redis:
|
||||
|
||||
```bash
|
||||
redis-cli ping
|
||||
```
|
||||
|
||||
检查 ASGI:
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:8000/health/
|
||||
```
|
||||
|
||||
生产 Nginx 必须为 `/ws/` 设置 `Upgrade` 和 `Connection` 请求头。详见 `docs/DEPLOYMENT.md`。
|
||||
Reference in New Issue
Block a user