Skip to content

fix(client): WebSocket 路由改用壳注入的 transport base - #768

Open
Max-Null wants to merge 1 commit into
omdsh-dev:mainfrom
Max-Null:fix/ws-base-desktop-shell
Open

Max-Null wants to merge 1 commit into
omdsh-dev:mainfrom
Max-Null:fix/ws-base-desktop-shell

Conversation

@Max-Null

Copy link
Copy Markdown
Contributor

问题

桌面壳(官方 Electron 壳)把页面放在自定义协议下:dsh-app://app/。此时 location.origin 是 dsh-app://app,而它的 host 是字面量字符串 app —— 不是网络主机。

插件用 new URL('/sidebar/ws/…', location.origin) 再换协议来拼 WebSocket 地址,于是得到 ws://app/sidebar/ws/…,DNS 永远解析不了。受影响的 socket:

  • /sidebar/ws/agent-opens(src/client/sidebar/use-host-feeds.ts)
  • /sidebar/ws/fs-watch(src/client/use-dir-watch.ts)
  • 同一构造模式的 agent-terminals / terminal

表现是控制台持续刷连接失败、功能静默退化(这两处的重连都有退避,最终会自停,所以用户只会看到报错而看不出功能已失效)。

证据

同一个页面里实测三种构造:

构造 解析结果 连接
new URL('/api/remote.mux', __DSH_TRANSPORT__.streamBaseUrl)(DSH 自己的 mux) ws://127.0.0.1:19388/api/remote.mux OPEN(2ms)
new URL('/sidebar/ws/agent-opens', __DSH_TRANSPORT__.streamBaseUrl)(本次改法) ws://127.0.0.1:19388/sidebar/ws/agent-opens OPEN(25ms)
new URL('/sidebar/ws/agent-opens', location.origin)(现状) ws://app/sidebar/ws/agent-opens ERROR(2704ms)

DSH 自己并不用 location.origin:packages/api/gateway/src/client/stream-client.ts 的 remoteStreamUrl() 读的是 globalThis.__DSH_TRANSPORT__?.streamBaseUrl ?? document.baseURI,注释写明「A shell-owned Host on another origin supplies that base through the transport」。原代码那句「Same construction the app's own downlink WebSockets use」的前提因此不成立。

改动

新增 sidebarWebSocketBase()(放在 src/client/desktop-env.ts —— 该模块本就只负责报告壳提供的事实),两处 socket 构造改用它:

const url = new URL('/sidebar/ws/agent-opens', sidebarWebSocketBase())
url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'

普通 http(s) 页面下 document.baseURI 与原 location.origin 等价,行为不变;仅在壳提供了 __DSH_TRANSPORT__.streamBaseUrl 时改用真实 Host 地址。

验证

  • 同机同页面只换 base:旧构造 ERROR、新构造 OPEN(见上表)。
  • 在一个基于官方桌面端的壳里替换后实测:控制台不再出现 ws://app/... 连接失败。
  • pnpm typecheck 通过;pnpm test 1138 passed。

一处与本改动无关的本地失败:tests/plugin-meta.spec.ts 的 “actually packs the icon and locales into the tarball” 在 Windows 上失败 —— tar -tzf 输出 CRLF,断言按 \n 分割后每项带 \r(得到 'package/LICENSE\r'),于是 'package/icon.svg' 匹配不上。该 spec 其余 5 个用例正常,本次未改动该 spec 与 package.json。

自定义协议下 location.origin 不能当 WebSocket base 用:官方 Electron 壳把页面
放在 dsh-app://app/,它的 host 是字面量 app,于是 /sidebar/ws/* 解析成
ws://app/...,DNS 永远解析不了 —— 终端的、agent-terminals、agent-opens、
fs-watch 四条 socket 全部连不上(控制台只见连接失败,功能静默退化)。

改为读 __DSH_TRANSPORT__.streamBaseUrl(DSH 自己的 downlink mux 用的同一来源),
普通 http(s) 页面回退 document.baseURI,行为不变。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants