You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cloud Run经反向代理后WebSocket连接失败问题求助

Cloud Run + WebSocket 自定义域名对接问题排查与解决

核心问题

长期使用Ambassador/Emissary作为API网关,采用架构客户端 -> Ambassador/Emissary -> Cloud Run -> FastAPI,已配置host_rewrite解决404问题,但WebSocket连接始终失败(客户端返回1006错误);相同配置对接GKE Autopilot时可正常运行。后续尝试改用Firebase Hosting路由(客户端 -> Firebase Hosting重写 -> Cloud Run -> FastAPI),WebSocket仍无法正常工作。

关键排查点与修复方案

1. Cloud Run WebSocket的强制要求

Cloud Run对WebSocket请求有严格的头信息要求,必须确保:

  • 请求头包含Upgrade: websocket和Connection: Upgrade,且这两个头不能被网关修改或移除
  • 网关必须透传所有WebSocket相关头,包括Sec-WebSocket-Key、Sec-WebSocket-Version、Sec-WebSocket-Protocol等

2. Ambassador/Emissary配置修正

针对映射配置,需补充以下关键设置:

  • 添加preserve_host: false,配合host_rewrite确保Host头正确传递给Cloud Run
  • 显式配置允许WebSocket升级:allow_upgrade: ["websocket"]
  • 禁用缓存相关头,避免网关干扰WebSocket连接请求

示例配置:

apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
  name: ws-mapping
spec:
  prefix: /ws/
  service: 你的Cloud Run服务域名.a.run.app
  host_rewrite: 你的Cloud Run服务域名.a.run.app
  preserve_host: false
  allow_upgrade: ["websocket"]
  headers:
    remove:
      - Cache-Control
      - Pragma

3. Firebase Hosting的WebSocket支持调整

Firebase Hosting默认对WebSocket转发有限制,需修改firebase.json:

  • 配置重写规则指向Cloud Run服务
  • 为WebSocket路径添加允许升级的头信息

示例配置:

{
  "hosting": {
    "rewrites": [
      {
        "source": "/ws/**",
        "run": {
          "serviceId": "你的Cloud Run服务ID",
          "region": "你的服务区域"
        }
      }
    ],
    "headers": [
      {
        "source": "/ws/**",
        "headers": [
          {
            "key": "Upgrade",
            "value": "websocket"
          },
          {
            "key": "Connection",
            "value": "Upgrade"
          }
        ]
      }
    ]
  }
}

注意:Firebase Hosting的WebSocket支持仅在特定区域可用,需确保Cloud Run服务未配置强制HTTPS重定向导致头信息丢失。

4. Cloud Run服务端验证

在FastAPI中确保WebSocket端点正确处理请求,示例代码:

from fastapi import FastAPI, WebSocket

app = FastAPI()

@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: str):
    await websocket.accept()
    while True:
        data = await websocket.receive_text()
        await websocket.send_text(f"收到消息: {data}")

同时查看Cloud Run服务日志,确认请求是否到达、头信息是否正确传递。

验证步骤

用curl测试WebSocket握手:

curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" -H "Sec-WebSocket-Version: 13" https://你的自定义域名/ws/test

若返回101 Switching Protocols,说明握手成功。

内容的提问来源于stack exchange,提问作者Martol1ni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:24:45