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

ASP.NET Core 6 SignalR Hub异步任务如何传递参数?

如何向SignalR Hub的异步任务传递参数?

针对你的场景,需要同时支持JavaScript客户端和SqlTableDependency事件触发时传递id、dis、dg三个参数到SendResults方法,以下是具体改造方案:

1. 改造ResultHub的SendResults方法

首先修改Hub中的方法,添加参数定义,同时优化依赖注入(避免在Hub构造函数中手动实例化仓储):

public class ResultHub : Hub
{
    private readonly ResultRepository _resultRepository;

    // 通过构造函数注入ResultRepository,需在Program.cs中注册该服务
    public ResultHub(ResultRepository resultRepository)
    {
        _resultRepository = resultRepository;
    }

    // 添加参数到SendResults方法
    public async Task SendResults(int id, int dis, int dg)
    {
        var results = _resultRepository.GetResults(id, dis, dg);
        await Clients.All.SendAsync("ReceivedResults", results);
    }
}

在Program.cs中注册ResultRepository服务(如果还没注册):

builder.Services.AddScoped<ResultRepository>(sp => 
{
    var config = sp.GetRequiredService<IConfiguration>();
    return new ResultRepository(config.GetConnectionString("DefaultConnection"));
});

2. 改造JavaScript客户端调用

在前端的InvokeResults函数中添加参数,并在connection.invoke中传入:

// 接收id、dis、dg参数,也可以根据实际场景从DOM元素读取
function InvokeResults(id, dis, dg) {
    connection.invoke("SendResults", id, dis, dg)
        .catch(err => console.error(err.toString()));
}

// 调用示例(比如绑定到按钮点击事件)
document.getElementById('btn-load-results').addEventListener('click', () => {
    // 从输入框获取参数值(示例)
    const id = parseInt(document.getElementById('input-id').value);
    const dis = parseInt(document.getElementById('input-dis').value);
    const dg = parseInt(document.getElementById('input-dg').value);
    InvokeResults(id, dis, dg);
});

3. 改造SqlTableDependency事件触发逻辑

注意:不能直接将ResultHub注入到SubscribeResultTableDependency中,因为SignalR Hub是短生命周期对象(每个连接创建一个实例),长生命周期服务持有Hub实例会导致上下文失效。正确做法是使用IHubContext<ResultHub>来发送消息,同时确定参数来源:

3.1 修改SubscribeResultTableDependency类

using Microsoft.AspNetCore.SignalR;
using TableDependency.SqlClient.Base.EventArgs;
using TableDependency.SqlClient.Base.Enums;

public class SubscribeResultTableDependency : ISubscribeTableDependency
{
    private SqlTableDependency<Result> _tableDependency;
    private readonly IHubContext<ResultHub> _hubContext;
    private readonly ResultRepository _resultRepository;
    // 定义参数(可根据实际场景从配置、数据库或变更记录中获取)
    private readonly int _targetId;
    private readonly int _targetDis;
    private readonly int _targetDg;

    // 通过构造函数注入IHubContext和ResultRepository
    public SubscribeResultTableDependency(IHubContext<ResultHub> hubContext, 
                                         ResultRepository resultRepository,
                                         IConfiguration configuration)
    {
        _hubContext = hubContext;
        _resultRepository = resultRepository;
        // 示例:从配置文件读取固定参数,也可以根据业务逻辑动态获取
        _targetId = configuration.GetValue<int>("ResultSettings:DefaultId");
        _targetDis = configuration.GetValue<int>("ResultSettings:DefaultDis");
        _targetDg = configuration.GetValue<int>("ResultSettings:DefaultDg");
    }

    public void SubscribeTableDependency(string connectionString)
    {
        _tableDependency = new SqlTableDependency<Result>(connectionString);
        _tableDependency.OnChanged += TableDependency_OnChanged;
        _tableDependency.OnError += TableDependency_OnError;
        _tableDependency.Start();
    }

    // 改为异步方法,因为SignalR发送消息是异步操作
    private async void TableDependency_OnChanged(object sender, RecordChangedEventArgs<Result> e)
    {
        if (e.ChangeType != ChangeType.None)
        {
            // 复用GetResults逻辑,发送消息给所有客户端
            var results = _resultRepository.GetResults(_targetId, _targetDis, _targetDg);
            await _hubContext.Clients.All.SendAsync("ReceivedResults", results);
        }
    }

    private void TableDependency_OnError(object sender, ErrorEventArgs e)
    {
        Console.WriteLine($"{nameof(Result)} SqlTableDependency error: {e.Error.Message}");
    }
}

3.2 在Program.cs中注册SubscribeResultTableDependency

builder.Services.AddScoped<ISubscribeTableDependency, SubscribeResultTableDependency>();

关键注意事项

  • 避免直接注入Hub实例:SignalR Hub是为单个连接设计的临时对象,长生命周期服务必须使用IHubContext来操作客户端。
  • 参数来源灵活性:如果SqlTableDependency触发时需要动态参数(比如从变更的Result记录中提取),可以从e.Entity中获取对应字段值,替换固定的_targetId等参数。
  • 类型安全:确保前端传递的参数类型和后端方法参数类型一致(比如前端传递整数,后端接收int),避免类型转换错误。

内容的提问来源于stack exchange,提问作者andreasS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:10:20