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

GitHub上Playwright测试中Socket.IO连接失败原因排查

GitHub CI中Socket.IO连接失败的排查与解决

问题背景

基于React开发的多人问答应用,使用Socket.IO实现客户端与服务端通信,用户登录后建立连接并渲染GameLobby组件。本地Chromium和Firefox环境下Playwright端到端测试正常通过,但推送到GitHub仓库后,CI流水线中的测试失败,控制台报WebSocket连接错误:

// chromium
WebSocket connection to 'ws://localhost:8181/socket.io/?EIO=4&transport=websocket&sid=URltd7CxRl-ryPZuAAAB' failed: WebSocket is closed before the connection is established.
WebSocket connection to 'ws://localhost:8181/socket.io/?EIO=4&transport=websocket&sid=TElu3sE0DVJJ9905AAAC' failed: Error during WebSocket handshake: Unexpected response code: 400
// firefox
"Firefox can’t establish a connection to the server at ws://localhost:8181/socket.io/?EIO=4&transport=websocket&sid=IeUT9q1NhUwqoEWPAAAP."

CI中健康检查步骤已通过,说明服务端HTTP接口正常,但Socket.IO连接失败。

可能的原因及解决方案

1. 前端环境变量配置错误

查看CI流水线中前端构建的环境变量配置:

env:
  VITE_SOCKET_PORT: 8181,
  VITE_SOCKET_ORIGIN: http://localhost

VITE_SOCKET_PORT值末尾多了一个逗号,会导致客户端读取到的端口是"8181,"而非8181,引发连接地址错误。

解决方案:去掉变量值后的逗号,修正配置:

env:
  VITE_SOCKET_PORT: 8181
  VITE_SOCKET_ORIGIN: http://localhost

2. Socket.IO跨域配置缺失或错误

CI环境中,前端静态服务可能运行在与本地不同的端口(比如Vite预览默认端口4173),如果服务端Socket.IO的CORS配置未允许该端口的来源,会导致WebSocket握手被拒绝。

解决方案:更新服务端Socket.IO的跨域配置,包含CI环境中前端的访问地址:

const io = require('socket.io')(server, {
  cors: {
    origin: ["http://localhost:5173", "http://localhost:4173"], // 包含本地和CI的前端端口
    methods: ["GET", "POST"]
  }
});

3. 前端静态服务未正确启动

当前CI流程只构建了前端,但未启动静态服务供Playwright访问。本地测试时依赖的是Vite dev server(5173端口),但CI中构建后需要启动预览服务。

解决方案:在CI中添加启动前端预览服务的步骤,并等待服务就绪:

- name: Build front end for E2E tests
  run: npm run build -w=client
  env:
    VITE_SOCKET_PORT: 8181
    VITE_SOCKET_ORIGIN: http://localhost

- name: Start front end preview
  run: npm run preview -w=client &

- name: Wait for front end preview to be ready
  uses: Jtalk/url-health-check-action@v3.2
  with:
    max-attempts: 5
    retry-delay: 5s
    url: http://localhost:4173 # Vite预览默认端口,可根据配置调整

同时修改测试用例中的访问地址,指向预览服务:

await page.goto('http://localhost:4173/');

4. Socket.IO服务未完全初始化

健康检查仅验证了HTTP接口/api/health,但Socket.IO服务可能在HTTP接口就绪后仍需时间初始化,导致测试执行时Socket连接端点尚未可用。

解决方案:

  • 扩展健康检查逻辑,在服务端的/api/health接口中,确保Socket.IO已完成初始化后再返回成功状态;
  • 或在健康检查步骤后增加一段延迟,给Socket.IO足够的启动时间:
- name: Wait for Socket.IO to initialize
  run: sleep 3 # 根据实际情况调整时长

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:05:18