修复自查发现的门禁与体验问题:格式、超时态语义、压缩 CPU 边界
Project CI / AI game creator shell Rust crates (pull_request) Successful in 4m48s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m3s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 6m33s
Project CI / Frontend tests (pull_request) Successful in 3m24s
Project CI / Backend tests (pull_request) Successful in 7m29s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m55s
Project CI / Repository checks (pull_request) Successful in 6m33s
Project CI / Native shell tests (pull_request) Successful in 9m0s

- 新增 Rust 测试补齐 cargo fmt;ESLint 按仓库约定收口:常量与解析函数拆到 platformGameLoadingSurfaceModel.ts,删除 GAME_PLAY_STARTUP_TIMEOUT_MS 常量别名(测试直接用共享常量)
- 共享加载面新增 stalled:宿主判定等待不再推进时停掉进度动画并把 aria-busy 置回 false(去掉与 role=status 重复的 aria-live)
- 后台试玩超时时传入 stalled,避免「一边转圈一边说超时」
- Accept-Encoding 权重参数名改为大小写不敏感(RFC 9110 §12.5.3),GZIP;Q=0 视为拒绝并补用例
- 发行资源压缩分级:≥2 MiB 改用 level 1(zlib 端实测约 1/3 耗时、压缩比差约 3%),小文件仍用 level 6
- 文档:主规范补压缩与条件请求契约(并写明 60 秒窗口与撤销窗口不放宽)、nginx README 修正 Pingora 压缩关闭时的口径、pitfalls 补 CPU 边界与措辞修正
This commit is contained in:
2026-10-05 18:02:48 +08:00
parent f58f51052c
commit d7c4f82d7d
13 changed files with 138 additions and 69 deletions
+1 -1
View File
@@ -105,7 +105,7 @@ curl -sSI -H 'Accept-Encoding: br' \
- 现役发行入口是平台同源路径 `https://<平台域名>/games/<gameId>/`。三份常驻模板(`genarrative.conf`、`genarrative-dev-http.conf`、容器 `deploy/container/nginx.conf`)都内联同一条同源发行入口 location,把 `/games/<gameId>/` 与 `/games/<gameId>/<asset>` 转发到 `api-server` 发行网关;不再需要独立发行域名、`*.games.<域名>` 通配 DNS 或通配 TLS。
- 该 location 的正则必须整体加双引号:`location ~ "^/games/(?<game_id>game_[0-9a-f]{32})(?<game_path>/.*)?$"`。不加引号时 nginx 会把 `{32}` 当块定界符,`nginx -t` 报 `pcre2_compile() failed: missing closing parenthesis`。
- 发行入口不使用 Cookie:边缘转发前设置 `proxy_set_header Cookie ""`;`api-server` 发行网关也会拒绝带 Cookie 的请求。响应头(`X-Content-Type-Options`、CORP、无凭据 CORS、HTML CSP、内容类型白名单、`ETag` 与 `Cache-Control: public, max-age=60, must-revalidate`)由 `api-server` 发行网关设置,边缘不覆盖。
- 传输编码:发行网关自己对文本类资源(HTML/JS/CSS/JSON/SVG/WASM,≥1 KiB)下发 `Content-Encoding: gzip` + `Vary: Accept-Encoding`,边缘的 gzip/Brotli 不会二次压缩(两边都以「上游已带 `Content-Encoding` 就跳过」收口)。因此直连 api-server(本地 dev 的 Vite 代理、或关闭边缘压缩的 Pingora 模式)时用户拿到的字节与生产边缘一致,不再出现「本地/未压缩边缘下引擎包原样 1.31 MiB」的落差。
- 传输编码:发行网关自己对文本类资源(HTML/JS/CSS/JSON/SVG/WASM,≥1 KiB)下发 `Content-Encoding: gzip` + `Vary: Accept-Encoding`,边缘的 gzip/Brotli 不会二次压缩(两边都以「上游已带 `Content-Encoding` 就跳过」收口),因此本地 dev(Vite 代理)与 nginx 边缘的用户口径一致,不再有「本地引擎包原样 1.31 MiB」的落差。注意 **Pingora 网关在自身压缩关闭时会移除请求里的 `Accept-Encoding`**,那种部署形态下源站压缩不生效、边缘也不压,属于网关侧口径(见 `docs/project-memory/shared-memory/pitfalls.md` 2026-10-05 条目)。
- 条件请求:命中 `If-None-Match` 时发行网关直接返回 `304`(无正文,保留 `Cache-Control` 与 `ETag`),所以 60 秒 `max-age` 之后的重复游玩只重验证、不重下整包;下架与换版仍按 60 秒窗口在新请求上生效。
- 隔离靠 iframe 沙箱而不是独立来源:游戏文档跑在 `sandbox="allow-scripts"` 的不透明来源里,读不到主站 Cookie、storage 与 DOM,离开页面即随 iframe 卸载。
- 审核通过时 `api-server` 按 gameId 派生同源路径 `/games/<gameId>/` 作为 `entryUrl` 写入公开投影,部署侧不再需要配置发行域名。换版本或下架只改变后端公开投影,边缘不需要改配置。