Skip to content

浏览器同源 6 连接上限导致多 tab 打开不同 canvas 时请求排队/无响应 #158

Description

@mydmdm

问题描述

同一浏览器打开 3 个 tab,分别访问同一台 server 上不同的 canvas(space),出现部分请求"卡住"的现象:agent profiles / model provider 等信息加载不出来。关闭其中 2 个 tab 后,剩下的 tab 立即恢复正常。

根因分析

  1. 每个 canvas 页面会对同一 origin 建立至少 2 条长期保持打开的 SSE 连接:

    • GET /api/canvas/:id/sync/streamapps/server/src/modules/canvas/sync.route.ts
    • GET /api/canvas/:id/external/streamapps/server/src/modules/canvas/external.route.ts

    若该 tab 内还有正在进行的 agent 对话,apps/server/src/modules/agent/agent.route.ts 中的 SSE 流端点会再占用一条连接。这些连接均设置 Connection: keep-alive,正常情况下不会主动关闭。

  2. 当前 server 走明文 HTTP(非 HTTPS),浏览器无法使用 HTTP/2 多路复用,只能退回 HTTP/1.1。浏览器(Chrome/Firefox/Safari)对同一 origin 的并发 TCP 连接数硬限制为 6 条

  3. 3 个 tab × 2 条 SSE = 6 条连接,正好占满浏览器对该 origin 的连接配额。此后任何 tab 发起的新请求(如 GET /api/acp/profilesGET /api/llm/models)都会被浏览器排队等待空闲连接,而不会真正发送到网络层——因此 server 端访问日志(apps/server/data/logs/server.log)中完全看不到这些"卡住"的请求。由于 SSE 连接被设计为长期保持打开,队列可能无限期得不到释放。

  4. 关闭 2 个 tab 后释放 4 条连接槽位,排队请求随即发出并成功,现象消失。

复现步骨

  1. 部署/运行一份 Huabu server(明文 HTTP,非托管反向代理),确保监听同一 host:port。
  2. 用同一浏览器打开 3 个(或以上)tab,分别访问同一 server 下不同的 canvas 路径(如 /canvas/<idA>/canvas/<idB>/canvas/<idC>)。
  3. 观察其中某个 tab 的 agent profile / model provider 等信息是否长期无法加载,同时 server 访问日志中无对应请求记录。
  4. 关闭其他 2 个 tab 后,问题 tab 应立即恢复正常。

建议修复方向(待评估)

  • 让 server 走 HTTPS(浏览器对同源 HTTP/2 连接走多路复用,不受 6 条限制)。
  • 合并 sync/streamexternal/stream 为一条 SSE/WebSocket 连接,减少每个 tab 占用的连接数。
  • 使用 SharedWorker / BroadcastChannel 让同一浏览器的多个 tab 共享一条到同一 canvas 的流式连接。

环境信息

  • Server 通过 pnpm start:webscripts/start-web.mjs)以纯 HTTP 方式监听 0.0.0.0:3001
  • 访问方式:浏览器直接访问 http://<host>:3001,未经 HTTPS 反向代理。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions