如何用k6调用ASP.NET Core SignalR Hub的JoinGameSession函数?
SignalR Hub 负载测试:调用服务器函数的解决方案
问题背景
我有一个基于ASP.NET Core Web API的SignalR项目,想通过k6做负载测试。目前已经能成功连接Hub,但不知道怎么调用服务器上的JoinGameSession函数。
现有代码
k6 连接代码(仅成功连接,无法调用函数)
import ws from 'k6/ws'; import { check } from 'k6'; export default function () { var token = "Bearer userAccessToken"; const url = 'wss://localhost:5001/session'; const params = { headers: { "Authorization": token } }; const res = ws.connect(url, params, function (socket) { socket.on('open', () => { console.log("opened"); socket.send(JSON.stringify({ UserId: "aUserId", GameId: "AGameId" })) }); socket.on('close', () => console.log('disconnected')); }); check(res, { 'status is 101': (r) => r && r.status === 101 }); }
服务器端Hub函数
public async Task<bool> JoinGameSession(JoinGameRequest request) { return true; }
官方SignalR客户端成功调用代码
const signalR = require("@microsoft/signalr"); require('dotenv').config(); var token = process.env.token ?? ""; var questionIndex = 0; let connection = new signalR.HubConnectionBuilder() .withUrl("http://localhost:5000/session", { headers: { "Authorization": token } }) .withAutomaticReconnect() .build(); connection.start().then(() => { connection.invoke("JoinGameSession", { UserId: "a", GameId: "x" }); }).catch(e => { console.log(e); })
解决方案
1. 修正k6代码,适配SignalR WebSocket协议
SignalR的WebSocket调用有固定消息格式,不能直接发送普通JSON。正确的消息需要包含type(消息类型)、target(目标函数名)、arguments(参数数组),如需接收返回值还要加invocationId。
修改后的k6代码:
import ws from 'k6/ws'; import { check } from 'k6'; export default function () { var token = "Bearer userAccessToken"; const url = 'wss://localhost:5001/session'; const params = { headers: { "Authorization": token } }; const res = ws.connect(url, params, function (socket) { socket.on('open', () => { console.log("opened"); // 构造符合SignalR协议的调用消息 const invokeMessage = JSON.stringify({ type: 1, // 1代表调用方法 target: "JoinGameSession", arguments: [{ UserId: "aUserId", GameId: "AGameId" }], invocationId: "1" // 需要接收返回结果时必填 }); socket.send(invokeMessage); }); // 监听服务器返回的调用结果(可选) socket.on('message', (data) => { const message = JSON.parse(data); if (message.type === 3) { // 3代表调用返回结果 console.log(`调用结果: ${JSON.stringify(message.result)}`); } }); socket.on('close', () => console.log('disconnected')); }); check(res, { 'status is 101': (r) => r && r.status === 101 }); }
2. 替代工具推荐
如果不想手动处理SignalR协议细节,可以用以下工具:
- Artillery:有专门的SignalR插件,可直接配置调用Hub方法,无需手写协议格式。
- Locust:通过Python脚本结合
websocket-client库模拟SignalR协议,实现负载测试。 - NBomber:.NET生态的负载测试工具,原生支持SignalR,适合熟悉.NET的开发者。
内容的提问来源于stack exchange,提问作者MoTahir
相关产品推荐
相关产品推荐

