Skip to content

Cloudflare Tunnel (HTTP/2 + CDN proxy) 导致 SSE 断连与 offline 状态 #771

Description

@ZyphrZero

环境

  • HAPI 版本:0.19.0
  • 部署方式:Cloudflare Named Tunnel + Cloudflare CDN(橙色云朵,代理模式)
  • 协议:HTTP/2(--protocol http2
  • 平台:Windows 11
  • cloudflared 版本:2026.5.2

现象

移动端(PWA / 浏览器)连接 https://hapi.<域名> 后,页面一直显示 offline 状态,无法创建新会话。切换到终端 Tab 后报错:

Disconnected: transport error

桌面端浏览器有时可以正常工作,但刷新或空闲一段时间后同样进入 offline。

排查过程

  1. cloudflared pre-check:TCP Connectivity 到 region1.v2.argotunnel.com:7844 失败(HTTP/2 is blocked),UDP/QUIC 通过。添加代理直连规则后 TCP 通过,HTTP/2 隧道建立成功。

  2. hub 与 runner 正常:本地 curl http://localhost:3006/ 返回 200,runner 日志显示 Machine registeredConnected to bot

  3. 源码分析

    • hub/src/socket/server.ts:使用 @socket.io/bun-engine,默认传输 ["polling", "websocket"]
    • hub/src/sse/sseManager.ts:SSE 管理器通过 sendHeartbeat 每 30 秒保活,依赖 HTTP 响应流的即时推送
    • hub/src/config/serverSettings.ts:CORS 由 publicUrl 自动派生
    • web/src/hooks/useTerminalSocket.ts:客户端 transports: ["polling", "websocket"]
  4. 根因定位:Cloudflare CDN 默认对 text/event-stream(SSE)响应启用缓冲(buffering),数据不会逐条推送到客户端,而是等累积到一定大小或连接关闭才发送。这导致:

    • SSE heartbeat 无法及时到达 → 客户端认为 hub 离线
    • Socket.IO polling 升级 WebSocket 也可能受 CDN 缓冲影响 → transport error

解决方案

在 Cloudflare 控制面板中为 HAPI 子域名规则中将缓存级别设置为绕过

Image

建议

是否可以在文档的 Cloudflare Tunnel 部署章节中补充这些 CDN 配置要求?或者考虑在代码层面通过检测 CDN 代理环境自动提示。

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:hubHub server (API, sync, store)area:webWeb PWA / React clientbugSomething isn't workingstatus:needs-reproNeeds reproduction steps

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions