fix(client): don't close a connected embed bridge on a late iframe load - #11
Open
fishOfOUC wants to merge 1 commit into
Open
fix(client): don't close a connected embed bridge on a late iframe load#11fishOfOUC wants to merge 1 commit into
fishOfOUC wants to merge 1 commit into
Conversation
The embed page posts `init` once per document and the parent only calls connectFrame() from that message, but frameLoaded() unconditionally closed the live port and restarted the readiness timer on every iframe `load` event. When `load` lands after the handshake — any slow or blocked subresource delays it past the SPA mount — the bridge is closed with no way to re-establish it, and the panel replaces a working store with its error face 5s later. Ignore `load` while a bridge port is live. Explicit reload, unmount, and connectFrame() itself still close the port.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What breaks
With
dsh10240.5.0 in awebprofile, opening the store (sidebar entry, or 设置 → 1024 Store) shows the embedded store for a moment and then replaces it with 「商店页面未能加载 / 可以重试、在系统浏览器打开主站,或检查本地壳更新。」 (or the English equivalent).The bridge is actually fine: it connects, and then gets torn down by a later event.
Root cause
plugin/client/client.js:The embedded page posts
{ type: 'init' }exactly once per document (from auseEffecton mount), and the parent only callsconnectFrame()from that message.frameLoadedruns on the iframe'sloadevent and unconditionally closes the liveMessagePortand starts the 5s readiness timer.loadwaits for every subresource, while the SPA mounts before that finishes. So whenever a subresource is slow or blocked — a browser extension blocking or delaying a third-party request is enough —loadlands after the handshake. The port is then closed, no secondinitever arrives, andconnectionflips to'failed'5s later. The store was working the whole time; only the panel state is wrong.Evidence
CDP instrumentation of both the GUI page and the embed document (it runs as an out-of-process iframe, so both were attached), same machine,
dsh10240.5.0,dsh webonhttp://127.0.0.1:3081, Chrome 148 with AdGuard AdBlocker loaded (which delays some embed subresources):Without extensions the race usually goes the other way (
loadfirst), which is why this is environment-dependent and not reported more widely.Fix
Ignore
loadwhile a bridge port is already live. The port is still closed on an explicit reload (reloadFrame), on unmount (useEffect(() => closeBridge, ...)), and byconnectFrame()itself before it opens a new one, so every other path keeps its current behavior.Verified end-to-end against a
dsh webserver serving this patched bundle, in the same extension-loaded browser that reproduces the bug:frame-loadstill lands ~200 ms afterready, and the panel stays on the store for the whole observation window with no fallback.Checks run in this branch:
npm test --workspace dsh1024→ 41/41 pass (includesscripts/preflight.mjs→preflight ok: dsh1024@0.5.0)Notes
plugin/client/client.jsis the committed artifact for the client half; nothing in this repository generates it, so the change is made there directly. If it is built from a source outside the repository, happy to move the change upstream of the build instead.中文摘要:嵌入页每个文档只发一次
init,父页只在收到init时connectFrame();而frameLoaded()在 iframe 的load事件里无条件closeBridge()并重启 5 秒计时器。当load晚于握手完成(子资源被扩展拦截或加载慢时就会如此),桥接被拆掉且无法重建,5 秒后就用「商店页面未能加载」盖住一个本来正常的商店。修复:已有活端口时忽略load。