CONTENTS · 目录(6)
我经常在手机上看一眼电脑里的 Agent 干到哪了,必要时接着发一句。电脑不止一台,所以手机上要在几台主机之间来回切。
我用的是社区的 Android 客户端 DSH Go。用久了有两个地方不顺手,于是分头动了手:
- App 里:切换 SSH 主机时,前一条连接会被释放,切回来又得重新连。这部分改在我的 fork 里,PR #1 已经合进 fork,同时在上游开了 issue #571 反馈。
- 电脑这边:我想让手机直接操作电脑上已经在跑的桌面端 Agent,于是在自己电脑上补了一条桌面网关。这是我本机的私有桥接,跟 App 的 PR 是两回事。
一、切主机时,别把上一条连接扔掉
原来的逻辑是“一次一台”:切到新主机,就释放前一条 SSH 连接;列表里主要也只显示当前这台的状态。只看一台机器的时候,这样没什么问题。但当你在两台电脑之间来回看进度,每次切回去都要重新握手,节奏就被打断了。
我加了一个开关:切换主机时保持 SSH 连接,默认关闭。

设置页里新增的开关,图中是默认的关闭状态。界面回归截图,主机信息是合成数据。
打开以后的行为是这样的:
- App 在前台时,已经用过的连接会保留,切回去直接复用;
- 它不会主动去连所有保存过的主机。你没碰过的那台,依然是没连接;
- App 进入后台约 5 分钟后,释放没在用的连接;正在进行的文件传输会等它先完成。
做成默认关闭,是因为保留连接本身就是一种取舍:多占一点资源,换来切换时不用等。这个选择应该由用户主动打开,而不是替所有人做了。
首版上手以后,切回去复用同一条连接这件事是成立的。
二、列表要回答两个不同的问题
一旦允许同时保留多条连接,主机列表就得同时回答两个问题:我现在选中的是哪台,以及哪些连接还活着。原来这两件事几乎是一回事,现在必须分开。

改动前的主机列表。底部那行“一次只连一台”说的是 DSH Remote 这一类接入,不是 SSH 开关的规则。界面回归截图,合成数据。

改动后的主机列表。勾号表示当前选中的主机;圆点和文字表示每条连接的状态:已连接、连接已断开、未连接。界面回归截图,合成数据。
现在的处理是:勾号只表示“当前选中”;每台主机另有灰、绿、红三种状态点,旁边配上文字。光靠颜色区分状态不够可靠,所以都配了字。
界面背后有几条我觉得比界面本身更重要的规矩:
- 列表只读状态快照。 为了显示一个绿点就去持有一条活连接,是本末倒置。展示状态和持有连接要分开。
- 每条连接都有自己的身份。 旧连接迟到的事件,不能覆盖新连接的状态。否则会出现刚连上又显示“已断开”这种很迷惑的界面。
- 该断的断,不该断的不断。 改了凭据或删除主机,对应连接的生命周期就会失效;只是改个名字,不会额外断开。
不同手机厂商的后台策略差别很大,最新这版的状态界面在这方面的表现,我还在实机上继续观察。
三、电脑这边:一条桌面网关
App 解决的是“连得上、切得快”。另一半问题是:连上电脑以后,手机能做什么。
我希望手机能直接操作电脑上已经在运行的桌面端 Agent:读会话、发消息、新建会话、停止、收通知。为此我在电脑上补了一条网关:
桌面网关的结构。手机连的是哪台电脑,就操作哪台电脑上的桌面端。
手机还是通过 SSH 连到目标电脑,访问那台电脑上只监听回环地址的网关。网关负责转换 DSH 协议,再借用已经在运行的桌面端的协调接口和本地 CDP 去干活。设计时参考过 ds-harness-remote。
有几件事是我刻意不做的:
- 不靠截图加模拟点鼠标。 那样做又脆弱又慢,而且出错了也说不清错在哪。
- 不另起一个独立的 app-server,假装成原生会话。 手机上看到的,就应该是桌面上那个真实的会话。
- 桌面端不可用时,直接返回明确的错误。 不会悄悄切到另一台主机去接力。手机连的是哪台,就只走哪台。
桌面侧补上的细节
真用起来以后,还补了一批细节:
- 附件上传、历史图片显示、下载回读;同名附件不会互相覆盖。普通文件上限 30MB,上传不是流式的。
- 切换模型的操作做了串行化,避免几次切换互相打架。
- 兼容导入进来但还是空的会话。
- 模型菜单按手机上的使用场景做了简化,桌面上完整的模型目录保持不变。
有两条规矩和“连接”这件事一样重要:
- 发送结果不确定时,不自动重发。 宁可让我自己看一眼,也不要同一条消息被执行两次。
- “停止”要确认停的是原来那一回合,并且是在同一个会话里,确认它真的进入了终态。界面被强行关掉,不等于背后正在跑的工具已经停了。
这和我在任务控制器里坚持的是同一个道理:状态不确定的时候,先去确认,不要用“再来一次”去掩盖不确定。
现在的状态
这部分测试分两类:协议和回归检查,以及在真机上复测。图片是目前最让我不放心的一路。11 月 4 日重连以后,第一张图发送已经恢复;但到了第二天,Claude 那一路又收到了发图的问题反馈。所以我不会说所有通道都已经好了,这一块还在磨。
几点体会
- 连接要有身份。 一旦允许同时保留多条连接,“这个事件是哪条连接发来的”就成了避不开的问题。
- 展示状态和持有状态要分开。 列表上的一个绿点,不应该反过来决定连接要不要活着。
- 不确定的时候,不重发。 无论是 SSH 上的一条消息,还是桌面上的一次停止操作,都是这样。
Claude Opus 5.5 辅助书写。