如何在Artillery中捕获Socket返回的bidAmount实现自动出价?
问题
我正在用Artillery对实时采购系统的HTTP Socket端点做性能测试。虚拟用户(VU)通过GUID加入join频道后,服务器会给频道内所有VU发送currentitem消息,消息是包含当前竞拍物品和出价信息的JSON数组。我需要提取其中的bidAmount加5后,向bid频道发送出价请求,但目前Artillery无法捕获Socket返回的消息,脚本里的capture配置不生效,求可行的实现方法。
服务器返回示例
[ "currentitem", { "itemCode":999, "itemCost":35, "bid":{ "user":{ "code":"M001", "name":"David" }, "bidAmount":10 } } ]
预期发送的出价请求
[ "bid", { "user":{ "code":"J001", "name":"John" }, "itemCode":999, "bidAmount":15 } ]
我的Artillery YAML脚本
config: target: 'https://example.com:8080/' payload: path: "users.csv" fields: - "code" - "guid" - "name" phases: - duration: 60 arrivalRate: 2 - engine: "socketio" flow: - emit: channel: "join" data: { "guid": "{{guid}}" } - capture: json: "$[1].bidAmount" as: "latestBid" - think: 2 - log: "{{name}} joined" - engine: "socketio" flow: - loop: - emit: channel: "bid" data: { "user": { "code": "{{code}}","name": "{{name}}" },"itemCode": 999,"bidAmount": {{latestBid+5}} } - think: 1 - log: "Bid" count: 720
解决方案
你的脚本存在几个关键问题导致capture失效,以下是修复步骤和修正后的脚本:
问题分析
- Engine配置位置错误:
engine应该放在config节点下,而非与phases同级,否则Artillery无法正确加载Socket.IO引擎。 - Capture未绑定目标事件:Socket.IO的消息是事件驱动的,需要明确监听
currentitem事件才能捕获对应返回数据,直接用capture节点无法关联到目标事件。 - Flow结构拆分错误:VU的行为流程(加入频道→监听消息→出价)应该在同一个
flow中完成,拆分两个flow会导致变量latestBid无法跨流程共享。 - YAML缩进错误:
loop节点下的子元素缩进不正确,会导致脚本解析失败。 - 变量计算类型风险:
latestBid捕获后可能是字符串类型,直接做加法会导致字符串拼接,需要转为数字后再计算。 - JSON路径错误:服务器返回的
bidAmount位于$[1].bid.bidAmount,原脚本的路径$[1].bidAmount指向不存在的字段,这是捕获失败的核心原因之一。
修正后的脚本
config: target: 'https://example.com:8080/' payload: path: "users.csv" fields: - "code" - "guid" - "name" phases: - duration: 60 arrivalRate: 2 engine: "socketio" # 正确放置engine配置位置 flow: - emit: channel: "join" data: { "guid": "{{guid}}" } - listen: # 监听服务器推送的currentitem事件 event: "currentitem" capture: json: "$[1].bid.bidAmount" # 修正JSON路径 as: "latestBid" - think: 2 - log: "{{name}} joined, latest bid is {{latestBid}}" - loop: # 修正缩进,确保子元素正确嵌套 - emit: channel: "bid" data: user: { "code": "{{code}}", "name": "{{name}}" } itemCode: 999 bidAmount: "{{ parseInt(latestBid) + 5 }}" # 转为数字后计算,避免字符串拼接 - think: 1 - log: "{{name}} bid {{ parseInt(latestBid) + 5 }}" count: 720
关键说明
listen节点:必须通过listen指定要捕获的Socket.IO事件,再在内部配置capture规则,才能正确捕获服务器主动推送的消息。- 变量类型处理:用
parseInt()将捕获到的latestBid转为整数,避免出现"10"+5变成"105"这类错误出价。 - YAML格式规范:所有子节点保持一致缩进(建议用2个空格),避免脚本解析失败。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

