dsh-anywhere
📱 专为 DSH iOS App 与多端协同打造的超级连接枢纽
电脑、iPhone、iPad 多终端同时在线无缝切换,实时同屏收发;局域网 + 通用稳定公网全覆盖,锁屏切回 0.25 秒极速自愈(Fast-Resume)。
🌟 核心杀手锏:完美搭配 DSH iOS App,实现真正的多终端无缝协同
传统 Web 访问或普通手机端连接 DSH 时,最令人头疼的三大痛点:
- 多端冲突踢线:电脑开着,手机一连就把电脑挤掉,或者两边状态不同步、各打各的;
- 手机一锁屏就假死:切出微信回个消息或锁屏几秒钟,再打开界面直接白屏、断线,必须手动刷新重新进;
- 输入流不同步:手机发了消息电脑看不到,或者电脑端正在打印流,手机端一片空白。
dsh-anywhere 深度重构底层传输与事件流,带来前所未有的「多端实时同屏」体验:
- 🤝 多终端同时在线,实时双向广播: 电脑端(桌面客户端或浏览器)、iPhone (DSH iOS App)、iPad 或多台移动设备可以同时打开同一个会话。无论哪一台设备敲下回车发指令,所有设备屏幕实时同步滚动、同步打印 AI 的流式回复,真正的“多端一心”。
- ⚡ 毫秒级锁屏断线自愈(Fast-Resume): 内置原生 Fast-Resume 协调机制。手机切到后台、锁屏挂起无论多久,只要重新点开 DSH iOS App,系统在 0.25 秒内自动完成静默换票重连,瞬间拉齐断网期间的所有消息增量,彻底告别白屏重载!
- 🔄 跨场景无缝切换: 在电脑前敲代码做方案,中途有事出门,直接拿起手机打开 DSH iOS App 继续聊,上下文与进行中的任务完全连贯,实现“电脑开始、手机随身走”的无缝闭环。
🚀 更多硬核能力
1. 统一 3083 端口主控(彻底告别双开冲突与端口漂移)
- 单进程绝对主控:无论是桌面端 DSH Desktop 还是无头模式,统一监听
3083端口,手机端与公网统一接入 3083。 - 彻底消除后台无头服务与桌面客户端的文件锁争抢(告别
stored session丢失),无论手机端还是电脑端,永远连入同一个进程,多端状态 100% 实时同屏!
2. 连接方式(推荐顺序:局域网优先,外网进阶)
- 🏠 首选:局域网直连(推荐所有用户)
- 手机与电脑连同一 WiFi,地址填
http://<电脑局域网IP>:3083(或直接扫码); - 局域网地址天然不变,零配置、零依赖、零风险,延迟最低,90% 的使用场景一台路由器就够了。
- 手机与电脑连同一 WiFi,地址填
- 🌐 进阶:外网远程访问(看自己的搭建能力,量力选择)
- 方案 A:免配置极速隧道(默认,开箱即用)
- 针对国内网络深度优化:内置国内镜像并发分片加速(亦可直接内置
bin/cloudflared.exe免下载),解决官方版在 GitHub 下载卡死在 0% 的致命问题; - 强制启用
--protocol http2隧道,杜绝国内运营商对 UDP/QUIC 的丢包阻断,普通用户点开即用。
- 针对国内网络深度优化:内置国内镜像并发分片加速(亦可直接内置
- 方案 B:Cloudflare Zero Trust 命名隧道(永久固定域名)
- 支持普通用户绑定自己的免费域名与 CF
Tunnel Token,重启软件外网网址永久不变。
- 支持普通用户绑定自己的免费域名与 CF
- 方案 C:自定义穿透直连(FRP / 异地组网 / 公网IP)
- 支持配合 SakuraFrp、OpenFrp、自建 FRP、Tailscale、ZeroTier 或公网 IP;
- 只需在设置中填入穿透地址,插件自动生成二维码并接管访问认证与多端协同。
- 方案 A:免配置极速隧道(默认,开箱即用)
3. 企业级安全防爆破
- 局域网与公网独立访问密码,支持自定义固定密码;
- 内置单 IP 防暴力破解防线:连续输错 5 次密码直接拉黑封禁该 IP 24 小时,杜绝公网扫描风险。
4. 老系统兼容:iOS 14 / 15 / 16.x 全通吃(含 16.3 及以下)
DSH 官方前端里用了 RegExp 后行断言((?<=…) / (?<!…)),这需要 Safari / iOS 16.4+。
在 iOS 16.3 及更低版本上,浏览器在解析期就抛 SyntaxError —— 整个几百 KB 的 vendor 包一行都不会执行,
页面直接白屏,任何 polyfill 都救不回来(语法级问题,不是运行期问题)。
本插件在代理层做了两道通用兜底,对所有用户生效,不需要改 App、也不需要改客户端:
- 正则字面量改写成运行期构造:把
/(?<=X)…/这类字面量替换成new RegExp("(?<=X)…")包一层函数。 新系统(iOS 16.4+)走try分支用原正则零开销;只有老系统才落到降级分支。 - 未知形态一律剥离:已知形态(
(?<!\S)、(?<=^|\s|\p{P}|\p{S}))做语义等价降级 (非捕获前缀 +exec内修正m[0]/m.index,捕获组编号不变); 其它没见过的形态则整体剥离后行断言 —— 匹配范围会放宽,但保证不崩、不白屏。 取舍很明确:宁可少匹配,也绝不让整页打不开。
同时 v flag(unicodeSets,iOS 17+)在做降级时自动降为 u,避免老引擎因 flags 非法再抛一次。
已知边界:不含后行断言、但用了
vflag 的纯字面量不做改写。原因是按/v反推正则起点会把a / v / b这类链式除法误判成正则,误伤代价(直接崩页)大于收益。当前 DSH 前端 v flag 命中为 0。
5. 手机端抽屉补「设置」入口
DSH 移动端抽屉里原本没有任何设置项 —— 真正的设置藏在底部「账号菜单」弹层里 (设置 / 意见反馈 / 退出登录),而抽屉是 280px 覆盖式的,一拉开就把正文工具条整个盖住, 用户根本找不到设置。本插件在抽屉里补一个齿轮:点它 = 打开账号菜单 → 点「设置」→ 自动收起抽屉(不收起的话 280px 抽屉会盖掉设置面板的 3/4,看起来像点了没反应)。
齿轮位置(v1.0.8 定版):贴在抽屉底部「账号菜单」那一行的右端,和头像同一行。
实测账号菜单行 x=10~270 / y=862~906(430×932),行内只有头像(1640)和昵称(48146),
146~270 是纯空白 —— 齿轮放 26×26 在 x=240,不压任何子元素,
点它和点账号菜单是同一套行为(打开账号菜单 → 点「设置」→ 自动收起抽屉),
即便盖住该行右端那点空白点击区,体验也完全不变。
位置演进说明:v1.0.6 放在「账号菜单右端 −40px」(
x=230~262),压住了账号菜单按钮右半边; v1.0.7 挪到抽屉外侧右边缘(x=287~315 / y=56~84),但那正好在主界面顶栏 「打开左侧侧边栏」按钮的高度带上,看起来像凭空多出一个按钮; v1.0.8 最终回到底部账号行右端,与头像同行。
零 DOM 结构改动、零布局影响。
📦 安装与配置
⚠️ 先看这条:不要用 npm i dsh-anywhere
npm 上那个 dsh-anywhere 不是这个插件。
npm registry : dsh-anywhere@0.1.2
maintainer : tangwenhao
repository : github.com/tangwenhao616-netizen/dsh-anywhere
published : 2026-08-18
它和本项目 同名但毫无关系——这个名字在 2026-08 就被别人占了,
所以本插件从未也没有在 npm 上发布过。pnpm add dsh-anywhere / npm i dsh-anywhere
装到的是别人的代码,不是这里的功能(没有 iOS 16.3 白屏自愈、没有抽屉设置齿轮)。
正确装法只有一种:走 GitHub 源。
1. 安装插件
在你的 DSH Profile 目录(如 ~/.dsh/profiles/desktop)下执行:
# pnpm
pnpm add github:liushQAQ/dsh-anywhere
# 或 npm
npm i github:liushQAQ/dsh-anywhere
走 GitHub 源的好处:
- 不需要 npm 账号、不需要发包,绕开名字被占和注册限制;
- 永远拿最新代码,仓库一提交就生效,不用等发版;
- 官方推荐的就是这个地址。
如果你之前误装过 npm 上那个同名包,先清掉再装:
pnpm remove dsh-anywhere
pnpm add github:liushQAQ/dsh-anywhere
也可以直接引用本地构建产物(把路径换成你自己的 tgz 位置;Windows 与 macOS / Linux 写法均可):
pnpm add /path/to/dsh-anywhere-<version>.tgz
2. 启用插件
在 settings.yaml 中配置启用(键名仍是 dsh-anywhere,取自 package.json 的 name):
plugins:
dsh-anywhere:
enabled: true
📱 搭配 DSH iOS App 使用指南
- 局域网同屏模式(极速低延迟):
- 手机连上与电脑相同的 Wi-Fi;
- 打开 DSH iOS App,地址输入:
http://<电脑局域网IP>:3083(或直接扫码接入)。
- 出门随身模式(公网无缝协同):
- 开启公网访问后,在 DSH iOS App 中输入公网地址;
- 无论身在何处,均可随时随地与家里的 DSH 实时对话,随时接续电脑上的工作。
⚙️ 配置文件说明(~/.dsh/dsh-anywhere/settings.json)
插件首次运行会自动生成纯净的通用配置,不包含任何个人敏感链接:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
lanEnabled |
boolean |
true |
是否开启局域网多设备访问 |
lanAuthEnabled |
boolean |
true |
局域网访问是否需要密码验证 |
tunnelMode |
string |
"quick" |
"quick"(自动隧道)/ "named"(CF固定域名)/ "fixed"(自定义公网直连) |
tunnelHostname |
string |
"" |
named 模式下的完整自定义域名 |
tunnelToken |
string |
"" |
named 模式下的 Cloudflare Token |
fixedWanUrl |
string |
"" |
fixed 模式下的自定义外部穿透地址(如 FRP) |
🗒 更新日志
v1.0.9
- 发布规范化:新增
LICENSE(MIT)与repository/homepage/bugs/author元数据;files白名单补LICENSE。 - 打包瘦身:清出 5 个历史
.bak备份(files里的目录项会整目录包含,.bak照样进包),包体积 5.01 MB → 1.09 MB,文件数 32 → 27。 - 文档通用化:安装示例的绝对路径改成占位
/path/to/dsh-anywhere-<version>.tgz;源码注释与构建产物里的内部措辞改为中性表述,client/client.js已重新构建。 - 齿轮定位改为以「账号行右界」与「抽屉右界」中更靠内的那个为基准(
anchor = min(ar.right, drawerRight),再左移 26+8px)。 起因:App 把抽屉宽度强制压到 252px 后,账号行仍排在 270,旧算法ar.right - 30让齿轮 right=266 —— 超出抽屉、被overflow:hidden裁掉右半边。 - 实测 430×932 / 393×852 / 375×667 三种尺寸,齿轮均完整落在抽屉内(right 230 / 208 / 198,抽屉右界 252 / 230 / 220)。
v1.0.8
- 设置齿轮回到底部账号行(用户反馈:齿轮落在了「打开左侧侧边栏」按钮的位置上,期望放在头像旁边):
v1.0.7 把齿轮挪到抽屉外侧右边缘,实测落在
x=287~315 / y=56~84, 那块正好在主界面顶栏「打开左侧侧边栏」按钮的高度带上,视觉上就是凭空多出一个按钮。 - 现在贴在账号菜单行右端(
ar.right - 26 - 4,与头像同一行垂直居中), 行内146~270本来就是空白,不压任何子元素;尺寸 26×26。 - 三尺寸实测(430×932 / 393×852 / 375×667):
insideAccountRow: true、overlapLabel: false(昵称右界 146,齿轮从 240 起)、clickable: true; 真点击 → 设置面板 414×651 打开、抽屉自动收drawerX: -150。
v1.0.7
- 修复设置齿轮压住账号菜单按钮(用户反馈:齿轮不该出现在页面 prompt 插件按钮的位置):
旧实现把齿轮放在「账号菜单右端 −40px」,实测 430×932 下落在
x=230~262 / y=868~900, 而账号菜单按钮本身是x=10~270 / y=862~906—— 齿轮整个压在账号菜单右半边, 把那片的点击全抢走(隐藏齿轮后逐点探测,底层清一色BUTTON.qin2_W_trigger)。 - 齿轮改到抽屉外侧右边缘(后被 v1.0.8 修正回底部账号行)。
- 新增五点位碰撞检测(
document.elementsFromPoint四角 + 中心)。 - 尺寸 32 → 28px。
v1.0.6
- 修复 iOS 16.3 及以下白屏(通用修复,非环境定制):
vendor 包里的邮箱正则是数组元素写法
[[/(?<=^|\s|\p{P}|\p{S})…/gu, Uf]], 前导字符是[,而改写器的「前导字符白名单」里没有[→ 判定不是正则起点 → 原样放行 → iOS < 16.4 解析期SyntaxError→ 整包不执行 → 白屏。白名单已补[。 - 改写器升级为真正通用:不再「只认两种已验证形态、其余放行」,任何后行断言都会被改写; 未知形态走整体剥离兜底(放宽语义保可用),混用多种形态的正则也能处理。
- 降级路径加固:二次构造
new RegExp全部包try,最后一级兜底返回空匹配正则, 任何情况下都不会再抛到调用方(原实现里二次构造失败会直接中断模块执行)。 vflag 降级:v→u,老引擎不再因 flags 非法二次抛错。- 缓存策略:bundle / asset 从
max-age=86400/31536000, immutable改为no-cache, must-revalidate—— 原来等于让手机把改写前的旧包锁死在本地, 代理层再怎么修都拿不到。 - 手机端抽屉补设置齿轮:抽屉右下角一键直达设置面板,并自动收起抽屉。
v1.0.5
- 适配最新版 DSH 内核,超越版本兼容,放宽 peerDependencies。
No comments yet. Be the first to write one.