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

JMeter发送的WebSocket socket.io请求无法被NestJS服务接收

问题现象
  • 部署的NestJS服务,使用如下socket.io-client代码可正常发起连接,服务端可成功接收连接:
const io = require('socket.io-client');
const socket = io("http://localhost:3000", {
    transports: ["websocket"],
    pingTimeout: 10000,
    pingInterval: 25000,
});
const someDelay = 10;
socket.on('connect', function () {
    console.log('connected...');
})
  • 上述客户端连接成功后会触发回调打印connected...日志,连接流程无异常。
  • 使用JMeter发起相同配置的WebSocket连接请求时,请求始终无法到达服务端;连接建立后携带token发起的后续请求同样无法被服务端接收,整个流程无显式报错但请求始终未触达服务端,请求响应采样器返回报错信息。
根因分析

核心原因是JMeter自带的通用WebSocket采样器仅支持标准原生WebSocket协议,不兼容Socket.IO的私有协议封装:
Socket.IO并非原生WebSocket实现,即便指定transports: ["websocket"]仅走WebSocket传输,它仍在标准协议之上做了私有封装,包括固定握手路径、协议版本校验、连接确认帧规则、消息帧格式约定、心跳逻辑等,直接用原生WebSocket采样器裸连,不符合Socket.IO的协议校验规则,请求会被服务端直接丢弃,不会进入业务逻辑层。

解决方案

方案1(推荐):使用Socket.IO专用JMeter插件

通过JMeter插件管理器搜索安装Socket.io Plugin,该插件原生适配Socket.IO协议逻辑,无需手动处理协议封装:

  • 配置时直接填写和JS客户端一致的服务地址http://localhost:3000
  • 传输协议选择websocket,同步配置和JS客户端一致的pingTimeout、pingInterval参数
  • 后续发送携带token的事件请求时,直接填写事件名和对应JSON载荷即可,插件会自动按Socket.IO协议格式封装帧内容

方案2:使用原生WebSocket采样器手动适配Socket.IO协议

如果不想安装额外插件,可按Socket.IO协议规则手动配置原生采样器的交互逻辑:

  1. 修正连接地址:不要直接连ws://localhost:3000,需使用Socket.IO固定握手地址格式:ws://localhost:3000/socket.io/?EIO=4&transport=websocket,其中EIO=4对应Socket.IO v4版本协议标识,需和服务端实际使用的Socket.IO主版本匹配;如果NestJS网关配置了自定义命名空间,地址中要补充命名空间路径。
  2. 完成握手确认:连接建立后,服务端会第一时间返回格式为0{"sid":"<会话ID>","pingInterval":25000,"pingTimeout":10000}的握手响应帧,收到该帧后必须立刻向服务端发送内容为40的文本帧,完成连接确认,否则服务端不会将该连接标记为有效连接,后续所有消息都会被丢弃。
  3. 按协议格式封装消息:后续发送业务请求(比如携带token的认证请求)时,不能直接发送原始JSON内容,需按照Socket.IO消息帧规则封装,格式为42["<事件名>",{token:"<你的token值>"}],其中42是Socket.IO普通事件帧的固定前缀,后面紧跟数组格式的内容,第一个元素是事件名称,第二个元素是事件携带的载荷数据。
  4. 保活配置:按照和客户端一致的间隔发送心跳帧(内容为2),收到服务端发送的3帧时无需额外处理,避免连接因心跳超时被服务端断开。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:24:22