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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:57:40