分片高速下载 · dsh-chunk-download
手机上的 Agent 下载助手:多连接分片、断了能续、下完直接进「下载」目录
在手机上的 DEEPSEEK_HARNESS 里让 Agent 下大文件:Range 分片并发 + 断点续传,断了接着下,
下完直接落在 Download/DeepSeekHarness;桌面端有侧边栏进度与会话标题栏胶囊。
纯 Node 实现,不用装 aria2 / curl 二进制。
适合谁
| 情况 | 说明 | |
|---|---|---|
| ✅ | 手机上让 Agent 下安装包 / 模型 / 视频 / 网盘直链 | 下完一键进「下载」,推送通知栏 |
| ✅ | 服务端对单连接限速(网盘直链、部分 CDN、GitHub Releases) | 多连接聚合,实测约 ×2.4 |
| ✅ | 不想装 aria2 / curl 二进制(macOS、ARM 服务器、手机容器) | 纯 Node,无原生依赖 |
| ❌ | HLS(m3u8) / 磁力 / BT | 不支持 |
| ❌ | 单连接已经跑满带宽 | 并行不会更快,与单线程持平(见实测) |
| ❌ | 想要网盘分享链接解析 | 那是另一类插件,需要各平台登录态 |
功能
| 能力 | 说明 | |
|---|---|---|
| 🚀 | Range 分片并发 | 1~64 条连接按 bytes=x-y 并行拉取,片数与分片策略见原理 |
| ⏯ | 断点续传 | 已完成分片位图 + 分片计划签名落盘,进程重启后能接着下 |
| ⏸ | 暂停 / 恢复 / 取消 | 运行中随时干预,暂停保留 .part,取消可连文件一起删 |
| 🧮 | 任务队列 | 同时跑 N 个任务(默认 2),其余排队;FIFO 调度 |
| 🐢 | 全局限速 + 单任务限速 | 令牌桶实现,所有连接合计不超设定速率 |
| 🛡 | 严格校验 | Content-Range 与请求必须匹配、实收字节数必须等于区间、文件大小变化即报错 |
| 🔀 | 自动回退单流 | 服务端忽略 Range(返回 200)或响应被 gzip 压缩时,自动退回单流下载,绝不写花文件 |
| 🕵️ | 停滞看门狗 | 单请求 30s 没数据即掐断重试,慢连接不拖死整个任务 |
| 📊 | 实时进度 | 桌面侧边栏 + 会话标题栏胶囊 + 浮动面板;工具侧也有进度条 / 速度 / ETA / 分片数 |
| ✅ | SHA-256 校验 | 传 sha256,下完逐字节核对;不匹配置为失败,可选删坏文件 |
| 🗂 | 同名策略 | ifExists: overwrite / skip / rename(另存为 name (1).ext) |
| 💽 | 磁盘预检 | 远端给了大小、本地空间不足时,开下前就拒绝 |
| 📦 | 批量下载 | 一次 urls 提交多条,逐条给出结果,一条失败不影响其余 |
| 🔔 | 完成通知 | 手机端走 3090 设备桥发通知栏消息;桌面端自动跳过 |
| 📱 | 送进手机 Download | 完成后通过 DSH 设备桥导出到 Download/DeepSeekHarness |
| 🔁 | 同链接去重 | 同一 URL + 同一目标文件已有任务时直接复用,不重复下载 |
| 🖥 | 跨平台 | Linux / macOS / Windows,Node ≥20;纯 Node 实现,无原生依赖 |
| 🧩 | 零依赖 | 只用 Node 内置模块,不需要 npm install 任何东西 |
为什么快
curl 单连接 ────────────── 48MB / 380KB/s / 130s ──────────────►
chunk-download ──┬── 1/8 ──┬── 2/8 ──┬── 3/8 ──┬ ... 8 路并行,聚合带宽
└─────────┴─────────┴─────────┘ 同一个文件,数倍的速度
- 分片数远多于连接数:按「每连接 8 片」给盈余片,worker 领完一片再领下一片(工作窃取), 避免某一片慢导致其他连接空转的“尾部塌缩”。
- 单片大小自适应:按文件大小档位规划(
<5MB不分片、<50MB8 片、<500MB32 片、更大 64 片), 单片不小于 256KB、总数封顶 512 片 —— 既不产生海量 Range 请求,也不会因为片太大而失去并行度。 - 失败只重试那一片:指数退避,已完成的片不重下。
安装
方式一:npm(发布后)
dsh plugin add dsh-chunk-download
方式二:本地目录 link(当前使用,推荐开发用)
DSH_HOME=/root/.dsh dsh plugin --profile web add /root/dsh-chunk-download
装完 dependencies 里是 link:/root/dsh-chunk-download、dsh.profile.bundles 自动带上包名;
改完源码重启会话即生效,不用重打包。
来源形式:本地目录
link:(与dsh-image-gen等社区插件的安装形态一致)。 升级只需git pull(或改文件)后重启;要分发时再用下面的 tgz。
方式三:本地 bundle 包(tgz,适合分发)
打成 npm 风格 tgz(
package/前缀):npm run pack:plugin # 生成 dsh-chunk-download-$(version).tgz在 DEEPSEEK_HARNESS 的插件管理里安装这个 tgz,启用
chunk-download,然后开新会话。工具列表里出现
chunk_download/chunk_download_status/chunk_download_control/chunk_download_wait即成功。
分发流程(npm 发布 / 插件目录 PR / Release)见 docs/publishing.md。
插件会往系统提示词注入一段“下载文件优先用
chunk_download”,让 Agent 自动走这条路而不是curl。
本地开发
git clone https://github.com/CXk253-chenxing/dsh-chunk-download.git
cd dsh-chunk-download
node --test # 24 个用例,全部用本地 HTTP 服务器,无需外网
npm i -D react react-dom && node --test test/render.test.mjs # 可选:把 UI 组件真渲染一遍
node bench/speedup.mjs 2 # 加速比演示
跨平台
| 平台 | 下载 | 导出到手机 |
|---|---|---|
| Linux / macOS / Windows | ✅ 纯 Node,路径用 path 处理;Windows 覆盖同名文件前会先删目标 |
—(无设备桥,自动跳过) |
| Android(DEEPSEEK_HARNESS) | ✅ | ✅ 走 3090 设备桥,落 Download/DeepSeekHarness |
桌面端没有设备桥时,export: true 会被跳过并在任务里记 exportError("已跳过导出;文件已保存在本地"),下载不受影响。
CI 在 Ubuntu × Node 20/22/24、macOS × 22、Windows × 22 上跑同一套测试。
界面
示意图,不是截图;深色主题下取色,浅色主题自动跟随 DSH 令牌。
装好后 DSH Web GUI 里会多出三处「安静但看得见」的进度,不用打开设置:
| 位置 | 表现 |
|---|---|
| 输入框上方整条(手机 + 桌面) | 文件名 / 进度条 / 百分比 / 速度 + 暂停、取消;点开是完整面板(手机端主要入口) |
| 会话标题栏(手机 + 桌面) | 进度胶囊:环形进度 + 百分比 + 实时速度;多任务时显示「N 个」 |
| 桌面侧边栏底部 | 一行摘要「下载 · N 个任务」+ 迷你进度条 + 百分比 |
| 点任意一处 | 桌面右下角浮动卡片 / 手机底部抽屉:任务列表、速度、剩余时间、暂停 / 继续 / 取消 / 导出到手机、全部暂停、清理已完成 |
数据来自宿主注册的同源接口(GET /chunk-download/tasks,有任务时 1s 轮询、空闲降到 4s、页面隐藏时暂停;
操作走 POST /chunk-download/control)。所有颜色取 DSH 主题令牌,明暗主题自动适配;图标为内联 SVG。
用法
1. 下载一个文件
// chunk_download
{
"url": "https://example.com/big.iso",
"dir": "/root/Downloads", // 可选,默认 ~/Downloads
"filename": "big.iso", // 可选,默认取 Content-Disposition / URL 末段
"connections": 16, // 可选,1~64,默认 8
"sha256": "74bb0f3a…", // 可选,下完校验摘要
"ifExists": "rename", // 可选,同名文件:overwrite / skip / rename
"export": true, // 可选,下完送进手机 Download/DeepSeekHarness
"waitMs": 60000 // 可选,阻塞等它下完(否则立即返回任务 id)
}
2. 跟进进度
// chunk_download_status(给 id 看单个,不给看全部 + 汇总)
{ "id": "dl_mvm1kptj_281a40" }
返回里带进度条、速度、ETA、分片完成数:
任务 dl_xxx ▶ 下载中
文件 /root/Downloads/node.tar.gz
进度 93.2% ███████████████████░ 45.0 MB / 48.3 MB
速度 6.4 MB/s · 剩余 10s
分片 111/128 片完成 · 16 连接并发
3. 干预与收尾
{ "id": "dl_xxx", "action": "pause" } // 暂停(保留 .part)
{ "id": "dl_xxx", "action": "resume" } // 恢复续传
{ "id": "dl_xxx", "action": "cancel", "deleteFile": true } // 取消并删 .part
{ "id": "dl_xxx", "action": "export" } // 完成后送进手机
{ "id": "dl_xxx", "action": "remove", "deleteFile": true } // 删任务记录(可连文件)
4. 阻塞等待
// chunk_download_wait
{ "id": "dl_xxx", "timeoutMs": 120000 }
5. 批量下载
// chunk_download
{
"urls": [
"https://example.com/a.zip",
"https://example.com/b.zip"
],
"dir": "/root/Downloads",
"connections": 8
}
一次最多 20 条;逐条返回结果,某条失败不影响其余。
网盘直链(需要带识别头)
{
"url": "https://cdn.example.com/file.zip",
"headers": {
"referer": "https://pan.quark.cn/",
"cookie": "你的登录态"
},
"connections": 16
}
直链通常对 Referer / Cookie / UA 敏感,缺了会 403;本插件只负责“更快地下”,不负责解析分享链接。
配置
cordis.patch.yml 里的 config(也可在插件管理里改):
| 键 | 默认 | 说明 |
|---|---|---|
dir |
~/Downloads |
默认下载目录 |
connections |
8 |
单任务默认并发连接数(1~64) |
maxConcurrentTasks |
2 |
同时运行的任务数,其余排队 |
speedLimit |
0 |
全局限速(字节/秒),0 = 不限 |
exportToPhone |
false |
true 时所有任务完成后自动导出到手机(桌面端自动跳过) |
autoResume |
true |
进程重启后自动续传未完成任务 |
retries |
4 |
单分片重试次数 |
requestTimeoutMs |
20000 |
探测 / 建连超时 |
stallTimeoutMs |
30000 |
单请求停滞多久判定死连接 |
notifyOnComplete |
true |
下载完成后发手机通知(桌面端自动跳过) |
stateDir |
$DSH_HOME/chunk-download |
任务状态目录(续传依赖它) |
promptSection |
true |
是否注入“下载优先用本插件”的系统提示 |
实测
2026-10-25 实测,家庭宽带 + 境内 CDN,同一文件、同一时段逐项对比。 之后没有复测(作者换了限速流量卡,再测没有参考价值)——把这张表当历史数据,不要当承诺。
| 场景 | 单连接 | 本插件 | 差距 |
|---|---|---|---|
2MB,本地服务器把单连接限速 256KB/s,8 连接(node bench/speedup.mjs 2,可复现) |
8.34s(0.24 MB/s) | 1.32s(1.51 MB/s) | 6.3× |
| 44.98MB 真实 CDN(npmmirror),8 连接,CDN 不限流时 | 4.5–5.8s(7.4–9.5 MB/s) | 2.1–2.3s(18–21 MB/s) | 约 2.4× |
| 同上,CDN 进入按 IP 限流时段 | 8–9s(≈5 MB/s) | 8–9s | ≈1×(限流按 IP 算,加连接无效) |
怎么读这张表:加速比只由服务端决定 ——
- 单连接被限速(网盘直链、部分 CDN、GitHub Releases)⇒ 收益最大,数倍;
- 单连接已经跑满线路带宽,或 CDN 按 IP 限流 ⇒ 并行不会更快,此时与单线程打平,不会更慢。
其它实测结论:
- 16 连接在 npmmirror 上反而容易触发限流(复测中出现过一次 31s 才下完,8 连接同文件 2.1s),这类 CDN 建议 8 连接;
- 内容校验:下载 48.3MB 的 Node 发行包,SHA-256 与官方
SHASUMS256.txt完全一致; export: true时手机Download/DeepSeekHarness里能直接看到成品。
工作原理
完整细节见 docs/how-it-works.md,要点:
Range: bytes=0-0探测总长度(校验Content-Range),拿不到就 HEAD 兜底;- 按文件大小与连接数规划分片数,单片 ≥256KB、总数 ≤512 片;
- N 个 worker 从共享队列领取分片,定位写入同一个文件(
fs.write(buffer, pos)); - 每片严格校验
Content-Range与实收字节数,不符即重试; - 已完成分片索引 + 计划签名落盘,续传时跳过已完成片;
- 服务端返回 200 或响应被压缩 ⇒ 放弃分片,回退单流。
同类项目
同类插件已经存在,按需选择:
| 项目 | 特点 | 什么时候选它 |
|---|---|---|
| @leisureyu/dsh-smart-dl | 内置 aria2,校验 / 批量 / 磁盘预检 / 进度面板,下载量最大 | 桌面端,想直接复用 aria2 引擎 |
| dlx-downloader | 分片 curl 引擎 + 侧栏面板 + 镜像故障转移 | 需要镜像自动重试 |
| dsh-downloader | 下载代理(自带节点),解决「连不上」 | 境外链路被墙 |
| 本项目 | 纯 Node 无二进制、1–64 连接、手机导出 + 通知、严格校验 | 手机端 / ARM / 不想装外部依赖 |
与 YunX 的关系
分片策略、校验规则、限速与测速思路参考了开源项目
YunX(云析) 的 Android 下载内核(Kotlin):片数 = max(档位, 连接数×8)、
单片 ≥256KB、封顶 512 片、Content-Range 严格匹配、忽略 Range 时回退单流等。
本仓库是 Node 版本的重新实现:把「part_N 临时分片 + 合并」换成「直接定位写最终文件」,省掉一次全量磁盘合并; 语言、运行时、并发模型都不同。但实现思路与分片参数来自 YunX,因此本项目同样以 AGPL-3.0-or-later 发布, 与上游保持一致;二次分发或提供网络服务时请遵守同一协议。感谢原项目的开源。
目录结构
dsh-chunk-download/
├── index.js # 插件入口:注册 4 个工具 + 系统提示 + 进度接口
├── client.js # 浏览器半身:侧边栏 / 标题栏 / 浮动面板
├── assets/ui-mock.svg # 界面示意图(README 用)
├── lib/engine.js # 下载内核(探测/分片/并发/续传/限速/队列/持久化)
├── lib/format.js # 进度条与人类可读文案
├── cordis.patch.yml # 插件层挂载配置
├── locale/{zh,en}.json # 插件管理里显示的名称与简介
├── icon.svg
├── docs/how-it-works.md # 原理、分片规划、协议校验细节
├── docs/publishing.md # npm 发布 / 插件目录 PR / Release 流程
├── docs/catalog-entry.yml # awesome-dsh-plugin 目录条目(可直接提 PR)
├── test/ # node --test:引擎 + 插件层端到端
├── bench/speedup.mjs # 加速比演示
└── .github/workflows/ci.yml # CI:node 20 / 22 / 24 跑测试
已知限制
- 只做直链下载,不解析网盘分享链接(那需要各平台登录态与逆向,风险与合规成本都不适合放进插件);
- 不支持 HLS(m3u8) / DASH / 磁力 / BT;
- 服务端不支持 Range 时只能单流(无法续传);
- 连接数过高可能撞上 CDN 对单 IP 的连接数限制(429 / 连接重置),此时调低
connections。
许可与致谢
本项目以 AGPL-3.0-or-later 开源,与 YunX(云析) 保持一致。
- 分片规划、
Content-Range校验、忽略 Range 时回退、令牌桶限速与滑动窗口测速等实现思路参考自 YunX(AGPL-3.0); - 按 AGPL 的要求:分发修改版、或以其对外提供网络服务时,必须同样以 AGPL-3.0 开放源代码;
- 完整文本见 LICENSE。
Copyright (C) 2026 CXk253-chenxing
No comments yet. Be the first to write one.