如何使用单个SignalR连接并行发送多条Hub调用消息
你遇到的串行执行是SignalR的默认行为:
- 服务端默认单个客户端连接最多同时处理1个请求,配置项
MaximumParallelInvocationsPerClient默认值为1 - 客户端用
await逐个调用test方法的写法,也会导致前一个请求完成后才会发起下一个请求
方案1:调整服务端并行配置(推荐,适用于ASP.NET Core SignalR 5.0+版本)
在服务端的SignalR注册逻辑中修改单客户端最大并行调用数:
// Program.cs 示例 var builder = WebApplication.CreateBuilder(args); // 注册SignalR时调整配置 builder.Services.AddSignalR(options => { // 可根据业务需求调整数值,默认是1,代表单连接串行处理请求 options.MaximumParallelInvocationsPerClient = 10; }); var app = builder.Build(); app.MapHub<你的Hub类>("/你的hub路由"); app.Run();
方案2:修改客户端调用逻辑,批量并行发起请求
不要逐个await每个invoke调用,先把所有请求的Promise收集起来,再统一等待完成:
async batchTest(): Promise<void> { try { const invokeTasks: Promise<void>[] = []; // 一次性发起3次请求 for (let i = 0; i < 3; i++) { console.log(`start ${i}: ` + new Date().toString()); // 不等待单个请求完成,直接把Promise存入数组 invokeTasks.push(this.connection.invoke('Test')); } // 等待所有请求处理完成 await Promise.all(invokeTasks); console.log('all requests finished: ' + new Date().toString()); } catch (err) { console.error(err); } }
兼容低版本SignalR的替代方案
如果你用的是没有MaximumParallelInvocationsPerClient配置的老版本SignalR,可以修改Hub方法让异步逻辑后台执行,快速释放请求管道:
注意:该方案下客户端会立刻收到请求完成的响应,无法获取方法实际处理结果,也无法捕获处理过程中的异常,仅适用于不需要返回值、不关心执行结果的场景
public Task Test() { // 丢弃异步任务的等待,直接返回完成 _ = Task.Run(async () => { Console.WriteLine($"Start: {DateTime.Now}"); await Task.Delay(1000); Console.WriteLine($"Stop: {DateTime.Now}"); }); return Task.CompletedTask; }
调整完成后你会看到服务端3个Start日志几乎同时打印,总耗时从原来的3秒降低到1秒左右,实现单连接并行处理请求。
内容的提问来源于stack exchange,提问作者gartenriese
相关产品推荐
相关产品推荐

