Artillery Socket.IO中socketio.query的{{token}}插值为undefined问题
解决Artillery Socket.IO负载测试中认证Token传递undefined的问题
问题根源
你遇到的问题是因为Artillery的socketio.query配置在加载阶段就完成模板插值,而socketio.beforeConnect钩子是在每个虚拟用户即将连接时才执行——这时候插值已经完成,自然拿不到还没生成的token,导致传递给服务器的是undefined。
正确解决方案
不要在YAML配置里直接用{{token}}插值,而是在beforeConnect钩子中直接修改Socket.IO客户端的连接参数,具体步骤如下:
调整YAML配置
移除socketio.query的配置,只保留基础的Socket.IO连接设置:config: target: "http://your-node-server:3000" phases: - duration: 60 arrivalRate: 10 socketio: transports: ["websocket"] processor: "./socket-hooks.js" # 指定钩子文件路径 scenarios: - name: "Authenticated Socket.IO connection" engine: "socketio" flow: - socketio.connect: namespace: "/" # 这里可以添加后续的Socket.IO事件交互逻辑编写钩子函数
在指定的socket-hooks.js文件中,通过beforeConnect直接修改客户端的query参数:module.exports = { socketio: { beforeConnect: (context, client, done) => { // 替换成你的实际Token生成逻辑(比如调用认证接口或本地生成JWT) const authToken = generateValidJwtToken(); // 直接设置Socket.IO客户端的查询参数 client.io.opts.query = { token: authToken }; // 如果后续场景需要用到token,也可以存到context.vars里 context.vars.token = authToken; // 必须调用done()让测试继续执行 done(); } } }; // 示例Token生成函数(根据你的实际需求替换) function generateValidJwtToken() { // 这里写你的JWT生成逻辑,比如使用jsonwebtoken库 const jwt = require('jsonwebtoken'); return jwt.sign({ userId: 'test-user' }, 'your-secret-key', { expiresIn: '1h' }); }
关键注意事项
- 确保钩子文件的路径在YAML的
processor中配置正确,否则钩子不会生效 - 钩子函数中必须调用
done(),否则测试会卡住 - 可以在钩子函数里加
console.log(authToken)确认Token生成正常,排查是否是Token生成逻辑的问题
内容的提问来源于stack exchange,提问作者Manish Kumar
相关产品推荐
相关产品推荐

