如何提升基于WebApplicationFactory的SignalR端到端测试速度?
优化SignalR测试连接速度的方案
核心问题定位
你遇到的StartAsync()慢的问题,主要源于默认传输协议协商的额外耗时(SignalR会依次尝试多种传输方式),以及每次创建HubConnection时重复初始化HTTP Handler带来的开销。
具体优化措施
1. 直接指定WebSocket传输,跳过协议协商
默认情况下SignalR会发起多次请求协商最优传输方式,直接指定WebSocket可省去这部分耗时:
var hubConnection = new HubConnectionBuilder() .WithUrl(_factory.Server.BaseAddress + "hub", options => { options.AccessTokenProvider = () => Task.FromResult(responseDict?["token"]); options.HttpMessageHandlerFactory = _ => _factory.Server.CreateHandler(); // 跳过协商,直接使用WebSocket options.Transports = HttpTransportType.WebSockets; }) .AddJsonProtocol(options => { options.PayloadSerializerOptions.Converters.Add(new JsonStringEnumConverter()); }) .Build();
2. 复用HttpMessageHandler
避免每次创建HubConnection时都调用CreateHandler(),复用同一个Handler可减少重复初始化开销:
// 在测试类初始化阶段创建一次Handler private readonly HttpMessageHandler _serverHandler; public YourTestClass(WebApplicationFactory<Program> factory) { _factory = factory; _serverHandler = _factory.Server.CreateHandler(); } // 创建HubConnection时复用已有的Handler var hubConnection = new HubConnectionBuilder() .WithUrl(_factory.Server.BaseAddress + "hub", options => { options.AccessTokenProvider = () => Task.FromResult(responseDict?["token"]); options.HttpMessageHandlerFactory = _ => _serverHandler; options.Transports = HttpTransportType.WebSockets; }) .AddJsonProtocol(options => { options.PayloadSerializerOptions.Converters.Add(new JsonStringEnumConverter()); }) .Build();
3. 关闭WebSocket心跳(测试环境无需保持长连接)
测试场景下不需要心跳机制,关闭后可减少额外网络交互:
var hubConnection = new HubConnectionBuilder() .WithUrl(_factory.Server.BaseAddress + "hub", options => { // ...其他配置 options.WebSocketConfiguration = socket => { // 禁用心跳 socket.KeepAliveInterval = TimeSpan.Zero; }; }) .AddJsonProtocol(options => { options.PayloadSerializerOptions.Converters.Add(new JsonStringEnumConverter()); }) .Build();
4. 禁用自动重连(测试场景不需要)
测试中连接断开直接终止测试即可,禁用自动重连避免不必要的重试逻辑:
var hubConnection = new HubConnectionBuilder() .WithUrl(_factory.Server.BaseAddress + "hub", options => { options.AccessTokenProvider = () => Task.FromResult(responseDict?["token"]); options.HttpMessageHandlerFactory = _ => _serverHandler; options.Transports = HttpTransportType.WebSockets; }) .AddJsonProtocol(options => { options.PayloadSerializerOptions.Converters.Add(new JsonStringEnumConverter()); }) .WithAutomaticReconnect(false) // 禁用自动重连 .Build();
额外建议
- 在测试类的初始化方法(如xUnit的
Setup)中提前创建HubConnection,避免每个测试方法重复初始化。 - 利用测试框架的夹具(如xUnit的
IClassFixture)复用WebApplicationFactory实例,减少应用重复启动的开销。
内容的提问来源于stack exchange,提问作者Levy Barbosa
相关产品推荐
相关产品推荐

