一次请求,
送上受控线路。
TurboDL 是一个 Kotlin/JVM 下载引擎,把探测、分片、并发与校验拆成清楚的阶段。控制权留在宿主,引擎负责让整条路线可观察、可恢复。
文件出现之前的五个检查点
路线为示意。下面的值均来自 TurboConfig.kt 的默认配置,不是实测速度。
-
01 已接收
请求
DownloadRequest
宿主提交 URL 与目标路径,任务进入有界队列。
-
02 范围就绪
探测
6_000 ms
一次 Range 请求确认大小、字节范围支持与校验器;不支持 Range 时退回整文件单流。
-
03 分片排队
分片
4x
为工作窃取安排分片:每连接约四块,并受块大小上限约束。
-
04 线路活动
并发
16
工作单元独立领取 Range;只有服务端背压时才自适应下调并发。
-
05 已核对
校验
字节一致
返回字节先与请求的 Range 对齐,再核对合并后的大小与终态事件。
塑造路线的默认值
这些是运行约束,不是速度承诺。每一行都是 TurboConfig.kt 的公开字段,宿主可按 client 覆盖。
路线图是示意;下表默认值可回到源码逐项核对。
| 配置字段 | 默认值 | 范围 | 运行影响 |
|---|---|---|---|
| maxConnectionsPerTask | 16 | 1..256 | 单任务默认并发线路数。 |
| maxConcurrentTasks | 3 | 1..64 | 有界的任务队列。 |
| segmentsPerConnection | 4 | 1..64 | 每条线路的工作窃取余量。 |
| blockSize | 16 MiB | 单块上限 | 更粗的分块降低请求扇出。 |
| tailAssistMinBytes | 256 KiB | 收尾阈值 | 低于此值继续拆分得不偿失。 |
| maxRetries | 5 | 0..50 | 单个分片的重试预算。 |
| probeTimeoutMs | 6,000 ms | 最小 1,000 | 探测有界,且不传输文件正文字节。 |
| stallTimeoutMs | 45,000 ms | 0 = 关闭 | 识别半死连接,不把正常抖动当故障。 |
真正有运行效力的控制项
这里只列当前有效、未废弃的开关。拨动仅演示状态,不会修改真实引擎实例。
收尾托管的历史开关;它与 tailAssist 同时为 true 才生效。
工作队列空后,空闲工作单元可以接管在飞分片的尾部。
只向下收敛。普通吞吐抖动不会减少线路数。
从配置的初始线路数逐步升速,而不是一次打开全部连接。
可选的预热有超时上限,不会无限拖延正式传输。
宿主已知大小时,跳过额外的元数据请求。
TurboConfig.kt · current defaults
一个仓库,七个独立站点
不安装插件框架,引擎也能完整工作。可选模块增加协议与宿主集成能力;依赖方向始终不反转。
-
turbodl-core必需HTTP Range 引擎、续传、重试、队列、DNS/代理。
-
turbo-plugin-runtime可选生命周期、清理、服务、事件与扩展点。
-
turbo-plugin-bootstrap可选一次调用装配基础运行时与 HTTP 后端。
-
turbo-plugin-hls可选HLS 点播清单、分片并发与 AES-128。
-
turbo-plugin-js可选加载 JavaScript 插件的 QuickJS 加载器。
-
turbo-plugin-parser可选微博、小红书与 Pixiv 分享链接解析。
-
turbodl-cli独立基于 SDK 的可脚本化 JAR,支持 NDJSON 输出。
失败即拒绝,而不是“差不多对”
官方插件会先写明不支持的输入,避免先产出一个损坏文件。这是产品边界,不是脚注。
| 插件 | 明确拒绝 | 为什么 |
|---|---|---|
| HLS VOD Backend backend.hls | 直播清单(没有 `EXT-X-ENDLIST`)DRM / `SAMPLE-AES`fMP4 `EXT-X-MAP`不连续标记 | 明确拒绝:不支持的流直接失败,而不是产出一个看起来正常、其实不对的文件。 |
| JavaScript Plugin Loader loader.js | 注册 `DownloadBackend`(字节面留在 Kotlin 一侧)发布服务(服务是 Kotlin 对象图)`require` / npm / `fetch` —— 宿主 ABI 就是全部可用面`jar:` 与远程脚本源(目前只支持本地文件 / `inline:` / `data:`) | 脚本负责算 URL、请求头和签名,从不经手下载数据流。这条边界正是它不会变成带宽瓶颈的原因。 |
| Platform Link Parser parser.platforms | 登录 — 需要会话的平台返回 null,由宿主自己的账号处理接手Pixiv 动图(ugoira):zip + 帧时长表需要图像处理Pixiv 小说需要签名的接口(抖音 / 快手 / B站):各自的签名算法仍留在宿主侧 | 它的结果类型不含任何路径:`DownloadRequest` 需要 `destination: File`,而解析发生在宿主决定目录之前。临时目录占位只在边界处补上,宿主仍然走自己的路径策略。 |
事件流就是宿主接口
引擎不画界面。它报告状态切换与字节计数,怎么呈现由宿主决定。
下面的事件名来自当前 CLI;数值仅用于说明格式,是示意数据。
{"type":"start","url":"<url>","output":"out.bin"}
{"type":"timing","stage":"metadata","t_ms":184,"probe_ms":96,"resume":""}
{"type":"progress","state":"downloading","downloaded":48234496,"total":167772160,"percent":28,"connections":16,"eta_ms":4000}
{"type":"completed","url":"<url>","file":"out.bin","bytes":167772160,"sha256":"<digest>"}
{"type":"summary","total":1,"failed":0}第一次下载之前
必须用 Android 吗?
不必。核心是纯 Kotlin/JVM,要求 JVM 17+。Android 只是可能的宿主之一。
必须安装插件框架吗?
不必。turbodl-core 不依赖插件框架。可选模块只增加能力。
坐标已经上 Maven Central 了吗?
还没有。当前支持的用法是 v0.4.1.0 附件里的离线 Maven 包。
服务端忽略 Range 会怎样?
返回字节会与请求的 Range 核对。不支持或撒谎的服务端不能悄悄把字节写到错误偏移。
能下载 HLS 吗?
点播 HLS 由官方 HLS 插件提供。直播清单、DRM、fMP4 与不连续序列会被明确拒绝。
图形界面在哪里?
这个仓库提供引擎、插件框架与命令行。它有意不把界面强加给宿主。