从 SFTP 部署到现场工作台:DeviceForge v2.6—v2.9 的一次完整演进
一款工业设备运维工具,真正的竞争力不只是“支持多少协议”,而是工程师在网络不稳定、设备数量增加、任务需要反复恢复时,能不能继续工作。
技术栈:Qt 6、C++17、CMake、FTP/FTPS、SFTP、Telnet/SSH、Modbus、OPC UA、WebSocket、TCP/UDP 中继
开头:从“能传文件”到“能完成现场任务”
工业设备的部署工作很少只有一个动作。工程师通常需要先连接设备,再浏览远程目录,确认版本文件,向多台设备分发内容,处理覆盖和权限问题,观察每台设备的进度,最后留下可复核的结果。
如果 FTP、SFTP、批量部署、文件浏览和失败重试分别由不同工具负责,现场就会不断发生上下文切换:路径要重新找,设备要重新选,失败要重新判断,已经成功的设备又可能被重复执行。
DeviceForge 从 v2.6 开始,沿着一条清晰的产品路线持续演进:
v2.6:打通 SFTP 批量部署
↓
v2.7:让双栏文件工作区真正可用
↓
v2.8:把批量部署变成可并行、可追踪的任务
↓
v2.9:用统一可靠性内核连接上传、下载和批量部署
这不是简单的功能叠加,而是从“协议能力”逐步走向“现场工作流”。
v2.6:SFTP 从“能浏览”走到“能部署”
v2.6 解决的是一个非常实际的边界问题:很多 Linux、Ubuntu 和云主机环境默认使用 SSH/SFTP,而不是 FTP。此前工具可以浏览 SFTP 文件,但真正部署时仍然需要切换协议或使用其他工具。
同一套部署语义覆盖 FTP 与 SFTP
v2.6 提取了 IDeployable 部署能力接口,把协议差异收敛在适配器内部:
uploadFile()
uploadFolder()
clearRemoteDirectory()
setProgressCallback()
setCancelFlag()
FTP 适配器和 SSH/SFTP 适配器分别实现底层 I/O,业务层沿用同一套部署循环。用户只需要选择协议、设备和目标目录,不需要为不同协议学习两套部署流程。
SFTP 文件夹部署的关键细节
SFTP 文件夹上传不是简单地把文件逐个发送出去。v2.6 的上传计划先递归生成目录和文件条目,确保目录创建发生在文件上传之前;清空远程目录时保留目标目录本身;每个文件和数据块都会检查取消标志。
这些细节决定了部署行为是否可预测:嵌套目录不会因为缺少父目录而失败,清空后仍然可以继续上传,取消操作也不会等到整批任务结束才生效。
v2.6 的产品意义
v2.6 的核心不是“增加了 SFTP 选项”,而是让 FTP 和 SFTP 在用户眼中成为同一种部署能力:同一处配置、同一套进度、同一种取消和失败语义。
v2.7:把文件操作从页面功能变成双栏工作区
当部署能力补齐之后,下一个问题变成了“工程师如何高效准备任务”。v2.7 围绕双栏文件面板做了系统化收尾。
统一本地与远程文件来源
IFileSource 将文件列表、创建目录、重命名、删除、上传、下载、连接和取消等能力抽象为协议无关接口。LocalFileSource 和 RemoteFileSource 负责各自的实现,FileBrowserPanel 只负责呈现和交互。
这样做的结果是:本地目录、FTP/FTPS 目录和 SFTP 目录都可以使用统一表格、路径栏、面包屑、右键菜单和拖拽逻辑。
Total Commander 式连续操作
v2.7 将双栏操作整理为熟悉的文件管理器语义:
- 双击目录进入,双击
..返回上级; - F2 重命名,F5 复制到对面面板,F6 移动到对面面板;
- Tab 切换左右面板;
- 远程面板支持系统文件拖入上传;
- 目录优先排序,
.与..保持稳定位置; - 远程目录读取异步化,慢网络不再冻结界面。
v2.7 还补上了异步场景中容易被忽略的可靠性问题:每次导航都带代际令牌,旧目录结果不会覆盖新路径;连接失败会自动重连并重试;SFTP 共享会话通过串行化保护,避免多个 worker 同时访问非线程安全的底层连接。
文件浏览的体验底线
文件管理器的价值不只在“能显示列表”,还在于操作不会被打断。路径栏、面包屑、连接状态点、错误提示和拖拽反馈共同构成了这个底线:工程师始终知道自己在哪个目录、当前是否已连接、一次操作是否真的完成。
v2.8:从逐台部署到并行批量部署
当目标设备从一台增加到十台、几十台,串行部署会明显拖慢现场节奏。但单纯增加并发线程并不能解决问题,真正需要的是可控的调度、独立的设备状态和可追溯的报告。
可配置的并发调度
v2.8 引入并行批量部署能力,部署并发度可在 1—8 之间配置并持久化。每台设备抽象为独立部署任务,由调度器根据并发上限分配执行资源。
设备列表
↓
DeploymentRunner
↓
并发度限制 + 取消传播
↓
每台设备独立执行与上报
用户不需要等待前一台设备完全结束后再手动点击下一台。与此同时,单台设备失败不会阻塞其他设备,失败设备也可以在任务结束后单独重试。
每台设备都有自己的进度和终态
批量部署最怕“总进度条显示 80%,但不知道哪台设备出了问题”。v2.8 为每台设备提供独立进度和终态:等待中、连接中、上传中、成功、失败、已取消。
取消也有明确边界:尚未开始的设备不会继续启动,正在传输的任务在安全检查点停止,所有未继续执行的设备统一记录为已取消。
报告让部署结果可以交付
v2.8 增加 CSV 和 HTML 部署报告,记录设备、文件、状态、失败摘要和耗时。报告不仅用于排查问题,也适合售后交付、版本归档和后续复盘。
从这一版开始,批量部署不再只是“同时点了很多次上传”,而成为一个有输入、有过程、有结果的任务系统。
v2.9:统一可靠传输闭环
v2.8 解决了并行批量部署,v2.9 进一步解决不同传输入口之间的语义割裂:双栏上传、双栏下载、本地复制/移动和批量部署,都应该遵循同一套可靠性规则。
一条统一的传输链路
TransferTask
↓
TransferScheduler
↓
TransferExecutor
↓
ITransferChannel
↓
FTP/FTPS 或 SFTP 通道
界面负责表达“用户想做什么”,调度器负责排队和并发,执行器负责重试、取消、校验和交付,协议通道负责具体 I/O。协议差异被隔离,可靠性语义被集中管理。
v2.9 的可靠性语义
- 瞬时网络错误可以有限重试;
- 认证、权限、路径和目标变化等确定性错误直接报告;
- 文件传输支持 SHA-256 校验;
- 临时文件完成后再提交,避免半文件被误认为成功;
- 非原子交付场景明确告警;
- 支持项目级取消和失败文件跳过;
- 批量任务保留 FTP/SFTP 目录映射、清空语义和部署报告。
这套闭环的核心思想是:成功必须有证据,失败必须能定位,取消必须有终态,恢复不能破坏已经完成的结果。
现场导航也属于可靠性
可靠性不只发生在传输线程里。v2.9 同时完善了双栏导航:
- 上下键选择文件和目录;
- 右方向键进入目录;
- 左方向键返回上级;
- 返回后自动重新选中刚才进入的目录;
- FTP CRLF 行结束不会再被误识别为目录名的一部分。
这些看似细小的行为,决定了工程师能否连续操作。一次返回不应该让用户重新寻找目录,一次服务器格式差异也不应该变成“URL 格式错误”。
四个版本,解决的是同一个问题
把 v2.6 到 v2.9 放在一起看,可以发现它们始终围绕同一条主线:让设备、文件和任务成为一个连续上下文。
| 阶段 | 主要问题 | 解决方式 |
|---|---|---|
| v2.6 | SFTP 能浏览但不能完整部署 | IDeployable 统一 FTP/SFTP 部署能力 |
| v2.7 | 文件操作割裂、慢网络易卡顿 | IFileSource + 双栏面板 + 异步目录加载 |
| v2.8 | 多设备部署慢且结果不清晰 | 并发调度、设备级进度、报告和失败重试 |
| v2.9 | 上传、下载、批量部署语义不一致 | TransferScheduler + TransferExecutor 统一可靠传输闭环 |
这条路线没有追求“功能数量最多”,而是持续减少现场操作中的断点。
一个完整的现场使用场景
假设需要把一个软件版本部署到多台 Linux 设备:
- 在 DeviceForge 中选择 SFTP,绑定目标设备;
- 左栏打开本地版本目录,右栏定位远程目标目录;
- 用方向键或双击检查目录结构;
- 将文件拖到远程面板,或者提交批量部署任务;
- 统一选择覆盖策略,避免任务过程中反复确认;
- 由调度器按并发度执行,实时查看每台设备状态;
- 网络短暂中断时执行有限重试;
- 对失败设备单独重试,成功设备不重复执行;
- 导出 CSV/HTML 报告,留存本次版本交付记录。
工程师始终围绕同一个工作区完成任务,不需要在 FTP 客户端、脚本窗口、批量部署工具和表格之间来回切换。
技术架构:让可靠性成为公共能力
DeviceForge 采用 Qt 6 + C++17,应用层使用 ToolBackend/ToolWidget 双层结构,协议访问通过 IProtocolAdapter 和 ProtocolRegistry 统一管理。文件工作区和传输内核进一步将 UI、业务编排和协议 I/O 分开:
FileBrowserPanel
↓
TransferTask / DeploymentJob
↓
TransferScheduler
↓
TransferExecutor
↓
ITransferChannel / IDeployable
↓
FtpAdapter / SshAdapter
异步 UI 使用代际令牌、QPointer 守卫和 queued callback,防止快速导航、重连和窗口销毁时出现旧回调覆盖新状态。配置通过 ConfigStore 持久化,敏感凭据使用 DPAPI 保护;日志遵循脱敏规则,不记录密码和不必要的原始通信内容。
适合哪些团队?
- 工业自动化、PLC 和嵌入式设备研发团队;
- 需要批量升级 Linux 网关、工控机和边缘设备的交付团队;
- 需要同时使用 FTP/SFTP、Telnet/SSH、Modbus、OPC UA 的调试人员;
- 需要把部署结果交付给客户或纳入版本归档的售后团队。
如果只是偶尔上传一个文件,普通 FTP 客户端已经足够;但如果你的工作包含多台设备、目录确认、失败恢复和结果交付,那么“工具是否能连续工作”就比“有没有上传按钮”重要得多。
当前边界与后续方向
DeviceForge v2.6—v2.9 已覆盖 FTP/FTPS/SFTP 文件浏览与部署、双栏文件管理、并行批量部署、报告导出和统一可靠传输。SCP 独立上传通道、跨平台 GUI、插件化 ToolHost 等能力仍属于后续路线,不把规划内容包装成当前已交付功能。
这也是项目希望坚持的发布方式:每个版本明确完成了什么、没有完成什么,并用测试和现场验证支撑功能描述。
结语:从工具集合走向现场伙伴
从 v2.6 到 v2.9,DeviceForge 完成了一次连续演进:
- 从 FTP 扩展到 FTP/SFTP 并行支持;
- 从文件浏览扩展到完整双栏工作区;
- 从逐台部署扩展到可配置并发和设备级报告;
- 从多个传输入口扩展到统一可靠性闭环。
最终目标不是让软件看起来更复杂,而是让工程师在真实现场少做重复确认,多保留有效进度;遇到慢网络、断线和失败时,知道系统正在做什么,也知道下一步从哪里继续。
DeviceForge 仍在持续演进。如果你正在维护一批工业设备,或者正在为团队寻找一个可以统一部署、测试和调试的桌面工具,欢迎访问项目主页、试用软件并提出 Issue。