.NET 6 WebAPI集成Ocelot网关后SignalR协商请求返回404
.NET 6 集成Ocelot后SignalR返回404问题修复
核心问题点
你遇到的404问题本质是中间件注册顺序错误 + 旧版路由写法与端点路由冲突,和Ocelot的路由规则本身无关:
- 中间件按注册顺序执行,你把
UseOcelot放在了SignalR端点映射MapHub之前,Ocelot执行时端点路由系统还未注册/myHub相关路径,匹配不到自身路由规则时直接返回404,不会将请求传递给后续中间件 - 你使用的
app.UseMvc()是.NET Core 3.0前的传统路由写法,在.NET 6+中会和SignalR依赖的端点路由系统产生匹配冲突 - 同步调用
UseOcelot().Wait()会阻塞请求线程,高并发下存在死锁风险
修复步骤
1. 重构Program.cs中间件顺序
严格遵循ASP.NET Core中间件注册规范,显式添加路由中间件,将本服务的端点(控制器、SignalR Hub)全部注册在Ocelot之前,替换UseMvc为适配.NET 6的端点路由写法,修正后代码如下:
builder.Services.AddOcelot(); // 原有AddMvc可替换为AddControllers,适配端点路由 builder.Services.AddControllers(); var app = builder.Build(); app.UseCors("AllowAllApps"); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // 端点路由必须先注册UseRouting app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); // 先注册所有本服务的端点,优先级高于Ocelot转发 app.MapControllers(); app.MapHub<MyHub>("/myHub"); // 最后注册Ocelot,未匹配到本服务端点的请求再交给Ocelot处理 // 去掉Wait(),改用异步等待避免死锁 await app.UseOcelot(); app.Run();
2. (可选)添加Ocelot路由优先级规则
如果调整顺序后仍存在路径匹配冲突,可以在Ocelot.json中显式配置高优先级规则,直接放过所有SignalR相关请求,不进入转发逻辑:
{ "Routes": [ // 高优先级规则,跳过/myHub路径转发 { "UpstreamPathTemplate": "/myHub/{everything}", "UpstreamHttpMethod": ["Get", "Post"], "DownstreamPathTemplate": "/myHub/{everything}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [{"Host": "localhost", "Port": 5001}], "Priority": 100 }, // 原有转发规则,优先级调低 { "DownstreamPathTemplate": "/{route}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [{"Host": "myotherapi", "Port": 80}], "UpstreamPathTemplate": "/myotherapi/{route}", "UpstreamHttpMethod": ["Post"], "AuthenticationOptions": { "AuthenticationProviderKey": "Bearer", "AllowedScopes": [] }, "AddHeadersToRequest": {"UserId": "Claims[sub] > value"}, "Priority": 0 } ], "GlobalConfiguration": {"BaseUrl": "http://localhost:5001"} }
3. Docker部署校验
- 确认CORS策略允许Docker容器间的源跨域访问
- 端口映射时需开放WebSocket协议升级所需的连接,不要仅限制HTTP POST请求
- 容器内服务监听地址不要绑定127.0.0.1,需绑定
http://*:端口或http://+:端口,否则跨容器访问会被拒绝
验证方式
部署后先直接请求http://localhost:5001/myHub/negotiate?negotiateVersion=1,如果返回包含connectionId、availableTransports的JSON响应,说明SignalR协商端点恢复正常,客户端即可正常建立连接。
内容的提问来源于stack exchange,提问作者Alternatex
相关产品推荐
相关产品推荐

