Skip to content

Unity 资源更新管理与弱网续传下载 ​

只更新一个头套,却要让用户重下整个安装包——这是 AssetBundle 只管压缩不管分发的必然结果。方案把资源从应用包里拆出来单独做版本管理,再配一个扛得住弱网断网的下载器。

技术问题 ​

虚拟直播产品的虚拟形象资源以 AssetBundle 形式分发,但 AssetBundle 只是一种压缩标准,本身不带版本管理和分发下载能力。于是传统的更新路径是:全部形象资源统一打包,连同编译后的程序二进制再压缩成一个版本文件推给用户。哪怕只改了一个头套,也要走完整流程,用户重复下载未变化的资源和二进制,开发端和用户端都浪费时间、存储和带宽。

下载侧还有一个引擎级的坑:UnityWebRequest 在断网重连后下载会卡住,且不触发 timeout——弱网环境下下载任务会无声无息地吊死。

现有方案不足 ​

  • 资源与应用强绑定:所有形象资源随应用版本发布,一个小更新要全量打包、全量下载,发布链路长、包体积大。
  • 无独立版本管理:资源的上下线和更新无法脱离应用发版节奏,运营侧想上下架一个形象必须等版本。
  • 弱网不可恢复:引擎下载接口在断网重连场景下存在卡死缺陷,没有续传和恢复机制,弱网用户下载失败率高。
  • 缓存无校验:本地缓存资源缺少一致性校验手段,可能命中损坏或非法资源。

核心思路 ​

资源侧:拆分与独立版本管理 ​

只把少部分形象资源打进应用包随版本发布,其余资源做独立的版本管理,在后台系统中维护更新和上下线。效果是三重的:应用包体积下降、资源更新不用发版、用户不重启应用就能拿到最新形象。

下载侧:三层架构下载器 ​

下载器按职责分三层,层间单向取用:

mermaid
flowchart TD
    A["配置层<br>提供下载所需固定参数"] --> D
    B["下载层<br>封面 / 列表 / 地址 / 文件下载接口"] --> D
    C["缓存层<br>缓存读写 / 一致性校验 / 下载状态"] --> D
    D["下载器核心<br>初始化读配置,下载调下载层<br>校验取缓存层比对"]
    D --> E["下载状态事件<br>下载中 / 成功 / 失败"]
    E --> F["观察者感知实时状态"]
  • 配置层:初始化时提供下载所需的固定参数,例如资源地址、版本标识、缓存目录等。
  • 下载层:对外提供四类接口——下载封面、下载模型文件、下载模型列表、获取下载地址;下载过程中维护缓存层的下载状态。
  • 缓存层:负责缓存读写、资源一致性校验和下载状态记录。

关键机制 ​

  • 弱网续传:不依赖引擎默认行为,在设定的超时窗口内按间隔主动重新拉起连接,窗口内恢复则继续下载,超时仍未恢复才判定失败——正面绕过断网重连卡死不触发超时的引擎缺陷。
  • 双端摘要比对:下载前先比服务器与本地缓存的资源摘要值,一致则直接读本地;下载后再比对落盘文件摘要,确认完整才算成功。提高缓存命中率,排除非法资源,也缓解服务器压力。
  • 登录态鉴权:请求携带登录态凭证,服务器鉴权通过才下发列表和下载地址,失败即返回错误。
  • 事件化状态:下载中、成功、失败三个事件对外广播,上层界面用观察者模式感知实时进度,不和下载逻辑耦合。

应用场景 ​

  • 虚拟直播 PC 端:虚拟形象资源热更新,不重启应用获取最新内容。
  • 弱网环境分发:网络不稳定场景下的资源续传下载。
  • 任何需要资源版本管理与分发解耦的 Unity 产品。

关联案例 ​

罗子初 · AI 座舱专家 · 8年端侧研发

Lv.1