Ocelot搭配SignalR报错连接未处于Connected状态无法发送数据如何解决
修复方案
1. 修正API网关中间件执行顺序
中间件顺序错误是导致连接失败的核心问题,SignalR的WebSocket握手和跨域请求需要优先处理,调整后网关代码如下:
// 网关ConfigureServices删除无用的AddSignalR注册,网关仅做转发不需要SignalR服务 public void ConfigureServices(IServiceCollection services) { services.AddCors(o => o.AddPolicy("CorsPolicy", builder => { builder .AllowAnyMethod() .AllowAnyHeader() .SetIsOriginAllowed(x => true) .AllowCredentials(); })); services.AddOcelot(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 跨域处理放在最前 app.UseCors("CorsPolicy"); // WebSocket握手处理放在路由和Ocelot之前 app.UseWebSockets(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); }); // Ocelot放在最后执行 app.UseOcelot().Wait(); }
2. 调整Ocelot路由配置,兼容SignalR请求
原配置仅支持ws协议,无法处理SignalR首先发起的HTTP协商请求,修改配置如下(如果使用的是旧版Ocelot,将Routes替换为ReRoutes即可):
{ "Routes": [ // 处理SignalR的WebSocket连接请求 { "DownstreamPathTemplate": "/messagehub", "DownstreamScheme": "ws", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 35685 } ], "UpstreamPathTemplate": "/messagehub", "UpstreamHttpMethod": [ "GET", "POST" ] }, // 处理SignalR协商请求和其他普通HTTP接口 { "DownstreamPathTemplate": "/{catchAll}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 35685 } ], "UpstreamPathTemplate": "/{catchAll}", "UpstreamHttpMethod": [ "POST", "PUT", "GET", "DELETE", "OPTIONS" ] } ], "GlobalConfiguration": { "BaseUrl": "http://localhost:44353" } }
3. 调整SignalR服务端可选配置
如果开发环境使用HTTP协议访问网关,注释掉SignalR服务端Configure方法中的app.UseHttpsRedirection(),避免HTTP请求被强制重定向到HTTPS导致连接中断。
4. 客户端连接地址适配
客户端连接SignalR的地址改为网关地址即可,示例:ws://localhost:44353/messagehub,如果网关启用HTTPS则对应改为wss协议。
内容的提问来源于stack exchange,提问作者Sid
相关产品推荐
相关产品推荐

