JMeter 中实现 双 WebSocket(双WS)连接
在 JMeter 中实现 双 WebSocket(双WS)连接 的测试场景(例如同时连接两个不同的 WebSocket 服务或同一服务的两个独立会话),可以通过以下步骤配置:
1. 场景需求
-
两个独立的 WebSocket 连接(例如
WS1
和WS2
)。 -
每个连接可能需要独立的请求、响应处理和协议消息编解码(如 Protocol Buffers)。
2. 准备工作
2.1 安装插件
-
确保已安装 JMeter WebSocket Samplers 插件(参考之前步骤)。
-
将 Proto 生成的 Java 类和
protobuf-java-x.x.x.jar
放入 JMeter 的lib
目录。
2.2 设计测试流程
-
连接1(WS1):打开连接 → 发送消息 → 接收响应 → 关闭连接。
-
连接2(WS2):同上,但可能指向不同地址或处理不同逻辑。
3. 配置双 WebSocket 连接
3.1 建立两个独立的 WebSocket 连接
在 线程组 中按顺序添加以下组件:
-
WebSocket Open Connection (WS1)
-
Server URL:
ws://server1:port/path1
-
Connection Name:
WS1
(自定义名称,用于区分连接)
-
-
WebSocket Open Connection (WS2)
-
Server URL:
ws://server2:port/path2
-
Connection Name:
WS2
关键点:通过
Connection Name
标识不同连接,后续操作需指定此名称。 -
3.2 发送消息到两个连接
为每个连接添加 WebSocket Request-Response Sampler:
-
WS1 Request-Response
-
Connection Name:
WS1
(必须与 Open Connection 一致) -
Request Data: 动态生成(通过 JSR223 PreProcessor)
-
Message Type:
Binary
-
-
WS2 Request-Response
-
Connection Name:
WS2
-
Request Data: 动态生成
-
Message Type:
Binary
-
4. 使用 JSR223 脚本处理双连接
4.1 为 WS1 生成 Proto 请求
在 WS1 Request-Response 下添加 JSR223 PreProcessor:
import com.your.package.MessageWS1;// 构建 WS1 的 Proto 请求
def requestWS1 = MessageWS1.newBuilder().setField1("value1").build();// 序列化并存储到变量
vars.putObject("payloadWS1", requestWS1.toByteArray());
配置 Request Data:
${__byteToString(${vars.getObject("payloadWS1")}, "ISO-8859-1")}
4.2 为 WS2 生成 Proto 请求
在 WS2 Request-Response 下添加 JSR223 PreProcessor:
import com.your.package.MessageWS2;// 构建 WS2 的 Proto 请求
def requestWS2 = MessageWS2.newBuilder().setFieldA(123).build();// 序列化并存储到变量
vars.putObject("payloadWS2", requestWS2.toByteArray());
配置 Request Data:
${__byteToString(${vars.getObject("payloadWS2")}, "ISO-8859-1")}
5. 解析双连接的响应
5.1 解析 WS1 响应
在 WS1 Request-Response 后添加 JSR223 PostProcessor:
import com.your.package.ResponseWS1;byte[] resWS1 = prev.getResponseData() as byte[];
ResponseWS1 responseWS1 = ResponseWS1.parseFrom(resWS1);// 保存字段到变量(前缀区分)
vars.put("ws1_status", responseWS1.getStatus().toString());
5.2 解析 WS2 响应
在 WS2 Request-Response 后添加 JSR223 PostProcessor:
import com.your.package.ResponseWS2;byte[] resWS2 = prev.getResponseData() as byte[];
ResponseWS2 responseWS2 = ResponseWS2.parseFrom(resWS2);// 保存字段到变量(前缀区分)
vars.put("ws2_data", responseWS2.getData().toString());
6. 处理异步消息(双工通信)
如果服务端会主动推送消息到客户端(非请求-响应模式),需使用 WebSocket Single Read Sampler 监听:
-
WS1 监听异步消息
-
WebSocket Single Read Sampler
-
Connection Name:
WS1
-
Timeout (ms): 设置合理超时时间
-
-
添加 JSR223 PostProcessor 解析消息:
byte[] asyncResWS1 = prev.getResponseData() as byte[]; if (asyncResWS1 != null) {ResponseWS1 asyncMsg = ResponseWS1.parseFrom(asyncResWS1);log.info("WS1 收到异步消息: " + asyncMsg.toString()); }
-
-
WS2 监听异步消息
-
同上,但指定
Connection Name
为WS2
。
-
7. 关闭双连接
在测试末尾添加两个 WebSocket Close Connection:
-
Close WS1
-
Connection Name:
WS1
-
-
Close WS2
-
Connection Name:
WS2
-
8. 完整测试结构示例
线程组
├─ WebSocket Open Connection (WS1)
├─ WebSocket Open Connection (WS2)
├─ 事务控制器(WS1 操作)
│ ├─ WebSocket Request-Response (WS1)
│ │ ├─ JSR223 PreProcessor(生成请求)
│ │ └─ JSR223 PostProcessor(解析响应)
│ └─ WebSocket Single Read Sampler (WS1)(监听异步消息)
├─ 事务控制器(WS2 操作)
│ ├─ WebSocket Request-Response (WS2)
│ │ ├─ JSR223 PreProcessor(生成请求)
│ │ └─ JSR223 PostProcessor(解析响应)
│ └─ WebSocket Single Read Sampler (WS2)
├─ WebSocket Close Connection (WS1)
└─ WebSocket Close Connection (WS2)
9. 关键注意事项
9.1 变量命名隔离
-
为不同连接使用不同变量名前缀(如
ws1_xxx
和ws2_xxx
),避免冲突。
9.2 连接独立性
-
确保每个操作的
Connection Name
正确指向对应的 WebSocket 连接。
9.3 资源释放
-
必须显式关闭连接,防止服务端连接泄漏。
9.4 性能优化
-
复用连接:在 WebSocket Open Connection 中勾选
Re-use connection
(如需复用)。 -
使用
Groovy
脚本并启用缓存。
10. 高级场景:双连接数据交互
如果 WS1 的响应需要作为 WS2 的请求参数:
// 在 WS1 的 PostProcessor 中提取数据
vars.put("ws1_token", responseWS1.getToken());// 在 WS2 的 PreProcessor 中使用该数据
def token = vars.get("ws1_token");
def requestWS2 = MessageWS2.newBuilder().setToken(token).build();
通过以上配置,可以实现双 WebSocket 连接的复杂测试场景,支持 Protocol Buffers 消息的独立编解码和异步通信。