Files
opendance-windows/project.yaml
T
zijunchiang 0ffb2d43bb test(ws): WebSocket 契约一致性验收(独立实现 × 包内 PoseServer)+ 故意不合规的负例服务端
tests/test_pose_server.gd 用的是**同引擎内的客户端**(Godot WebSocketPeer),而真实
对端是 Android(Kotlin/OkHttp)——同引擎自测会共享同样的假设(超时判定、分包、
文本/二进制边界、关闭语义、子协议协商),于是「测试全绿」不等于「Android 连得上」。
契约 §7 也写明:静默超时要用保活避免,而不是靠重连掩盖;这句话只有用独立实现的
客户端实测才算验过。

新增三个文件:
  * build/integration/probe-ws.gd —— 把**包内** PoseServer 跑起来(--main-pack +
    只加载包内代码),把连接/控制帧/帧/断开事件汇总成 JSON 报告;自身不做判定
    (避免「用被测实现判定被测实现」)。支持 --stop-file 提前收尾。
  * build/integration/ws-client.mjs —— Node 实现的契约一致性客户端(用内置
    WebSocket,零依赖),逐条跑 §1 §1.1 §2 §3.1-§3.6 §5 §6 §7 的场景。
  * build/accept-ws.sh —— 编排:解包 → 起探针 → 等监听 → 跑客户端 → 收报告 →
    核对客户端看不到的那一半(frames_dropped / malformed_frames / 控制帧计数 /
    device_replaced / 关闭原因 / 静默超时消息带毫秒数与阈值)。

实测(**已发布**的 v0.2.3 资产重新下载后跑):客户端 30 通过 / 0 失败 + 服务端侧
16 项事实全过。关键两条:
  * 保活对照:只发应用层 ping 持续 19 秒(> 静默超时 15 秒)连接**仍保持打开**;
  * 静默超时:完全不发数据 → close(1001,"timeout"),实测 15011 ms(阈值 15000 ms);
另有:子协议协商、welcome 声明保活参数且 heartbeat(5000) < silentTimeout(15000)/2、
pong 原样回传 sentAtMs、同 deviceId 替换旧连接(1000 "replaced by new connection")、
bye → 1000、协议不匹配 → bye + 1002、72 帧含故意跳号(服务端 frames_dropped=3)
与故意 100 字节非法帧(malformed_frames=1)。

反向验证:新增**故意不合规的服务端** build/integration/probe-ws-bad.gd
(welcome 不声明保活字段、不带 sessionId、收到 ping 不回 pong、不做 deviceId 去重),
对同一客户端 → 14 项 ✗、退出码 1,证明断言不是空转。

踩坑记录(已写入任务文档):
  1. --script 模式下从无类型数组取 peer,peer.get_packet() 返回类型推不出来,
     var x := … 直接 Parse Error;
  2. 复核静默超时消息时写了否定式断言 !includes("静默超时 1"),把正确行为判成失败 ——
     断言应写成正向模式匹配;
  3. 探针原本只能按固定时长跑,编排脚本得猜时间;改成客户端跑完 touch stop 文件。

顺带:package-release.sh 结尾把三条发布前验收(产物自证 / WS 契约一致性 / 跨端集成)
一次列全。不影响已发布的 v0.2.3 产物,故不新发版本。
2026-09-17 05:32:24 +08:00

123 lines
4.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
project: opendance-windows-client
version: 0.2.3
repository: opendance-windows
default_branch: main
engine: Godot 4.7.2
contracts_version:
rest-api: 0.5.0
websocket-keypoints: 0.2.0
data-models: 0.7.0
skeleton-topology: 0.2.0
model-formats: 0.5.0
database: 0.4.0
# 契约变更流程(文档 7.2):
# 任何跨端契约变更必须先在 opendance-web 修改 contracts/ 并提升版本,
# 再在本项目创建适配任务。本项目内的 contracts/ 只是只读快照。
dependencies:
- name: opendance-web
kind: rest-api
contract: contracts/rest-api.yaml
usage: 曲目/动作/模型目录与关键点序列
- name: opendance-android
kind: websocket-consumer
contract: contracts/websocket-keypoints.md
usage: 本端为服务端,Android 主动连入推流
tasks:
- id: T-WIN-001
file: tasks/001-scaffold.md
scope: Godot 项目骨架
status: done
- id: T-WIN-002
file: tasks/002-rest-client.md
scope: 调用 Web 服务端 API
status: done
- id: T-WIN-003
file: tasks/003-websocket-receiver.md
scope: 接收 Android 关键点帧
status: done
- id: T-WIN-004
file: tasks/004-keypoint-deserialize.md
scope: 239 字节帧反序列化
status: done
- id: T-WIN-005
file: tasks/005-vrm-loader.md
scope: VRM 模型加载
status: done
- id: T-WIN-006
file: tasks/006-skeleton-retarget.md
scope: 关键点 -> VRM 骨骼重定向
status: done
- id: T-WIN-007
file: tasks/007-scoring-dtw.md
scope: DTW 评分引擎
status: done
- id: T-WIN-008
file: tasks/008-game-ui.md
scope: 主界面 + 游戏界面 + 结算
status: done
- id: T-WIN-009
file: tasks/009-source-display.md
scope: 模型/动作来源信息展示
status: done
- id: T-WIN-010
file: tasks/010-about-page.md
scope: 关于页面 + 开源声明
status: done
- id: T-WIN-011
file: tasks/011-build-script.md
scope: Windows 打包脚本
status: done
- id: T-WIN-012
file: tasks/012-about-version.md
scope: 「关于」清单展示当前版本号
status: done
- id: T-WIN-013
file: tasks/013-scene-selection.md
scope: API 升级 rest-api 0.5.0 + 场景选择 + 物理落地
status: done
- id: T-WIN-014
file: tasks/014-full-package.md
scope: 发布整包(单个 zip + SHA256SUMS,不拆分卷)
status: done
- id: T-WIN-016
file: tasks/016-aabb-transforms.md
scope: 场景包围盒沿树累乘变换(修复入树前用 global_transform 导致的 ERROR 与范围偏位)
status: done
- id: T-WIN-015
file: tasks/015-keepalive-dedup.md
scope: 连接保活 / 设备去重 / 状态机(契约 websocket-keypoints 0.2.0,与 T-AND-011 对齐)
status: done
- id: T-WIN-017
file: tasks/017-pe-version.md
scope: 发布包 exe 的 PE 版本资源(Windows 属性页显示的文件/产品版本)必须等于发布版本
status: done
- id: T-WIN-018
file: tasks/018-release-acceptance.md
scope: 发布包级端到端验收(读包内 pck:版本号 / 界面显示值 / 契约表 / 资源可加载)
status: done
- id: T-WIN-019
file: tasks/019-cross-end-integration.md
scope: 跨端集成验收(包内客户端 × 真实 Web 服务端)+ 补 Motion.thumbnailUrl 契约字段
status: done
- id: T-WIN-020
file: tasks/020-ws-contract-conformance.md
scope: WebSocket 契约一致性验收(Node 独立客户端 × 发布包内 PoseServer)+ 故意不合规的负例服务端
status: done
deliverable:
artifact: opendance-windows-v0.2.3.zip
packaging: Godot 导出脚本(Linux 直接导出 / Windows 兜底)
release_rules: # 文档 §5.7 硬性要求
- 单个完整包,禁止 .partN 分卷
- 同时上传 SHA256SUMS(裸文件名,可直接 sha256sum -c)
includes:
- OpenDance.exe
- OpenDance.pck
- THIRD_PARTY.md
- README.txt
- README.md
- contracts/ # 当前版本契约快照