Signal R集成测试连接失败:无法在连接启动前访问传输管道
问题:集成Azure SignalR的ASP.NET Core服务测试时连接异常
场景与服务配置
在ASP.NET Core中配置了集成Azure SignalR的SignalR服务,配置代码如下:
builder.Services.AddSignalR(options => { options.ClientTimeoutInterval = TimeSpan.FromMinutes(5); }).AddAzureSignalR(); builder.Services.AddCors(options => { options.AddDefaultPolicy(builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); }); app.UseCors(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapHub<MyHub>("/Chat");
测试代码
使用WebApplicationFactory进行测试的代码如下:
var client = _factory.CreateClient(); var connection = await StartConnectionAsync(_factory.Server.CreateHandler(), "Chat"); private static async Task<HubConnection> StartConnectionAsync(HttpMessageHandler handler, string hubName) { var hubConnection = new HubConnectionBuilder() .WithUrl(new Uri($"http://localhost:5124/{hubName}"), o => { o.HttpMessageHandlerFactory = _ => handler; o.Credentials = null; }) .Build(); try { await hubConnection.StartAsync(); } catch(Exception ex) { Console.WriteLine(ex.ToString()); } return hubConnection; }
异常信息
建立连接时出现如下异常:
'this.Transport' threw an exception of type 'System.InvalidOperationException' "Cannot access the Transport pipe before the connection has started."
可能的原因与解决办法
Azure SignalR服务未在测试环境适配:服务配置中启用了Azure SignalR,但测试时WebApplicationFactory启动的是本地服务器,没有实际连接Azure SignalR服务,导致客户端无法完成传输协商。解决办法是在测试环境禁用Azure SignalR,改用本地SignalR实现:
在测试项目的WebApplicationFactory子类中重写配置逻辑:protected override void ConfigureWebHost(IWebHostBuilder builder) { builder.ConfigureServices(services => { // 移除已注册的Azure SignalR服务 var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(ISignalRServerBuilder)); if (descriptor != null) { services.Remove(descriptor); } // 重新添加本地SignalR服务 services.AddSignalR(options => { options.ClientTimeoutInterval = TimeSpan.FromMinutes(5); }); }); }测试URL的端口硬编码问题:测试代码中硬编码了端口
5124,但WebApplicationFactory的测试服务器使用动态端口,应该使用服务器的实际BaseAddress:
修改StartConnectionAsync中的URL配置:// 改用测试服务器的BaseAddress构造Hub地址 var hubConnection = new HubConnectionBuilder() .WithUrl(new Uri(_factory.Server.BaseAddress, hubName), o => { o.HttpMessageHandlerFactory = _ => handler; o.Credentials = null; }) .Build();连接失败后未处理无效连接:虽然捕获了
StartAsync的异常,但如果连接启动失败,返回的hubConnection处于未连接状态,后续访问Transport属性就会触发该异常。测试中应确保连接成功后再使用,添加状态检查:await hubConnection.StartAsync(); // 断言连接已成功建立 Assert.Equal(HubConnectionState.Connected, hubConnection.State);
内容的提问来源于stack exchange,提问作者zooes
相关产品推荐
相关产品推荐

