Skip to content

fix(gateway): support structured app-host messages - #48

Closed
gaoweifan wants to merge 1 commit into
RyensX:mainfrom
gaoweifan:fix/app-host-object-messages
Closed

fix(gateway): support structured app-host messages#48
gaoweifan wants to merge 1 commit into
RyensX:mainfrom
gaoweifan:fix/app-host-object-messages

Conversation

@gaoweifan

Copy link
Copy Markdown

问题

在 ChatGPT Windows App 26.825.51511 上,OpenCodex 无法完成 AppHost RPC
注册,页面可能停留在 Codex 图标,并出现以下日志:

Failed to register AppView RPC services
MessagePort message error.
non_string_message_from_official

OpenCodex 现有 AppHost relay 只接受字符串或 null,因此会丢弃官方
MessagePort 发送的结构化对象。

根因

从本机安装的 ChatGPT Windows App 26.825.51511 官方 bundle 中可以确认,
AppHost transport 使用 structuredClonable 编码,并直接通过 MessagePort
发送值。其等价逻辑为:

encodingLevel = "structuredClonable";

send(value) {
  port.postMessage(value);
}

在该模式下,普通对象、数组、BigInt、Date、undefined 和 byte view 等值会以
结构化数据通过 MessagePort,而不保证被预先转换为字符串。

修复前的 OpenCodex relay 对所有非字符串、非 null 数据只记录
non_string_message_from_official 并直接丢弃,导致 AppHost RPC 请求无法继续,
随后端口关闭并触发 MessagePort message error

修改内容

  • 增加 AppHost RPC 的 JSON/WebSocket transport codec:

    • 支持 primitive、普通对象、数组、BigInt、Date、ArrayBuffer、DataView 和 TypedArray。
    • 保留旧版字符串和 null 帧兼容。
    • 严格校验 wire tuple、字段类型、对象键、base64、typed-array byte length 和 encoding。
    • 保留深度、节点数量和 BigInt 位数防护。
  • 收紧 AppHost relay 生命周期:

    • 使用 relay identity 和 generation 防止旧 relay 的延迟回调影响 replacement relay。
    • 每个 relay 最多向浏览器发送一个 terminal error 或 close 事件。
    • codec、WebSocket 或 MessagePort 转发失败只关闭对应端口。
    • 一个端口失败不会影响同一客户端的其他端口或其他客户端。
    • 保持 WebSocket reconnect 后 connect 和首帧的 FIFO 顺序。
  • 对齐 MessagePort 关闭语义:

    • 官方到浏览器方向仅将 null 视为关闭。
    • undefined 作为结构化值转发。
    • 浏览器发送 null 或 undefined 后只关闭一次,不追加重复 terminal 帧。
    • WebSocket 尚未 ready 时保留 terminal 帧,避免断线期间丢失。
  • 让 smart-scheduling、model-router presentation 和 token-usage 消费者同时接受
    已解码的结构化 RPC 与旧版字符串 RPC,不改变现有协议路由和 UI 行为。

  • 显式保留 WebSocket 入站的 100 MiB maxPayload
    该限制属于 WebSocket 网络边界,不是 codec 或 MessagePort 的消息限制。

兼容性

该 codec 仅用于在 AppHost MessagePort 与 JSON WebSocket 之间传输当前 RPC
实际使用的结构化值,并继续兼容旧版字符串和 null 帧。它不是通用的
structured-clone 实现,也不改变现有协议路由或 UI 行为。

验证

  • pnpm test:191/191 通过
  • pnpm run build:gateway:通过
  • 相关 JavaScript 文件 node --check:通过
  • git diff --check origin/main...HEAD:通过
  • pnpm run launcher:pack:win:通过
  • pnpm run launcher:dist:win:成功生成 Windows x64 NSIS 安装包和 ZIP
  • 使用 ChatGPT Windows App 26.825.51511 部署当前提交并重启验证:
    • 页面正常加载
    • AppHost RPC 注册成功
    • 可以发送消息并持续接收输出
    • AppHost WebSocket relay smoke test 通过
    • 在重新启动后的正常使用验证区间内,未再出现
      MessagePort message errornon_string_message_from_official
      或 missing-relay 错误

@RyensX

RyensX commented Sep 1, 2026

Copy link
Copy Markdown
Owner

感谢PR!但目前主分支做了大量的改进,该PR有大量冲突,请解决完冲突并按新标准重新实现 :)

@gaoweifan
gaoweifan force-pushed the fix/app-host-object-messages branch from 3c9b116 to a73a271 Compare September 2, 2026 11:52
@gaoweifan

Copy link
Copy Markdown
Author

上游仓库已经在commit 78ed0559(feat(compatibility): support structured app-host messages)中实现了相同的 AppHost 结构化消息兼容修复,并已合并到 main 分支。因此本 PR 的修改已经被上游实现覆盖,不再需要重复合并。

@gaoweifan gaoweifan closed this Sep 2, 2026
@RyensX

RyensX commented Sep 2, 2026

Copy link
Copy Markdown
Owner

上游仓库已经在commit 78ed0559(feat(compatibility): support structured app-host messages)中实现了相同的 AppHost 结构化消息兼容修复,并已合并到 main 分支。因此本 PR 的修改已经被上游实现覆盖,不再需要重复合并。

是的,目前已经支持新版。再次感谢你的贡献!

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