Ocelot 没有将 websocket 传递给微服务
Ocelot not passing websockets to microservice
我正在尝试使用 Ocelot 作为代理连接到 SignalR 集线器。 SignalR 插入微服务,网关通过 websockets 流量。通过 HTTP 请求的协商成功执行,但通过 websockets 的进一步通信似乎丢失了。我不知道发生了什么,尤其是当使用另一个环境上的 Azure SignalR 时,与相同配置的通信工作得很好。下面我展示了我的网关配置:
ocelot.json
{
"DownstreamPathTemplate": "/{anyHub}/negotiate",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "communication",
"Port": 80
}
],
"UpstreamHttpMethod": [ "POST" ],
"UpstreamPathTemplate": "/{anyHub}/negotiate",
"ReRouteIsCaseSensitive": false,
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
},
"DelegatingHandlers": [
"IdentityInQuery"
]
},
{
"DownstreamPathTemplate": "/{anyHub}",
"ReRouteIsCaseSensitive": false,
"DownstreamScheme": "ws",
"DownstreamHostAndPorts": [
{
"Host": "communication",
"Port": 80
}
],
"UpstreamPathTemplate": "/{anyHub}",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
},
网关的一部分Program.cs
.Configure(async app =>
{
await app
.UseCors(cors =>
{
cors.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed(x => true)
.AllowCredentials();
}).UseOcelot();
if (turnOnWebsockets)
app.UseWebSockets();
特定的微服务集合扩展:
public static ISignalRBuilder AddSignalRConfiguration(this IServiceCollection services, bool isDevelopment)
{
var newServices = services.AddSignalR();
if (!isDevelopment) newServices.AddAzureSignalR(Config.AzureSignalROptions.ConnectionString);
return newServices;
}
public static IServiceCollection AddSignalRCors(this IServiceCollection services)
{
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed(x => true)
.AllowCredentials();
}));
return services;
}
IApplicationBuilder 扩展的一部分,特别是微服务:
public static IApplicationBuilder AddSignalR(this IApplicationBuilder app, bool isDevelopment)
{
app.UseRouting()
.UseCors("CorsPolicy");
if (isDevelopment)
{
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<UserHub>("/userHub");
endpoints.MapHub<ConversationHub>("/conversationHub");
endpoints.MapHub<DiscussionHub>("/discussionHub");
});
}
....
return app;
}
如何将 websockets 与 Ocelot 和 SignalR 一起使用?网关目前能够与 SignalR 通信的唯一传输方法是长轮询,但对我来说它并不完全令人满意。预先感谢您的帮助!
中间件顺序很重要。
if (turnOnWebsockets)
app.UseWebSockets();
需要在 UseOcelot
调用之前发生。
例子
像这样的东西应该适合你
.Configure(async app =>
{
app.UseCors(cors =>
{
cors.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed(x => true)
.AllowCredentials();
});
if (turnOnWebsockets)
app.UseWebSockets();
app.UseOcelot().Wait();
备注
AFAIK async Configure
目前在 ASP.NET Core 中不受支持。使用 .Wait()
通常是不受欢迎的,但在这种情况下它是必需的,也是 Ocelot documentation 鼓励的方式。
我正在尝试使用 Ocelot 作为代理连接到 SignalR 集线器。 SignalR 插入微服务,网关通过 websockets 流量。通过 HTTP 请求的协商成功执行,但通过 websockets 的进一步通信似乎丢失了。我不知道发生了什么,尤其是当使用另一个环境上的 Azure SignalR 时,与相同配置的通信工作得很好。下面我展示了我的网关配置:
ocelot.json
{
"DownstreamPathTemplate": "/{anyHub}/negotiate",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "communication",
"Port": 80
}
],
"UpstreamHttpMethod": [ "POST" ],
"UpstreamPathTemplate": "/{anyHub}/negotiate",
"ReRouteIsCaseSensitive": false,
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
},
"DelegatingHandlers": [
"IdentityInQuery"
]
},
{
"DownstreamPathTemplate": "/{anyHub}",
"ReRouteIsCaseSensitive": false,
"DownstreamScheme": "ws",
"DownstreamHostAndPorts": [
{
"Host": "communication",
"Port": 80
}
],
"UpstreamPathTemplate": "/{anyHub}",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
},
网关的一部分Program.cs
.Configure(async app =>
{
await app
.UseCors(cors =>
{
cors.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed(x => true)
.AllowCredentials();
}).UseOcelot();
if (turnOnWebsockets)
app.UseWebSockets();
特定的微服务集合扩展:
public static ISignalRBuilder AddSignalRConfiguration(this IServiceCollection services, bool isDevelopment)
{
var newServices = services.AddSignalR();
if (!isDevelopment) newServices.AddAzureSignalR(Config.AzureSignalROptions.ConnectionString);
return newServices;
}
public static IServiceCollection AddSignalRCors(this IServiceCollection services)
{
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed(x => true)
.AllowCredentials();
}));
return services;
}
IApplicationBuilder 扩展的一部分,特别是微服务:
public static IApplicationBuilder AddSignalR(this IApplicationBuilder app, bool isDevelopment)
{
app.UseRouting()
.UseCors("CorsPolicy");
if (isDevelopment)
{
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<UserHub>("/userHub");
endpoints.MapHub<ConversationHub>("/conversationHub");
endpoints.MapHub<DiscussionHub>("/discussionHub");
});
}
....
return app;
}
如何将 websockets 与 Ocelot 和 SignalR 一起使用?网关目前能够与 SignalR 通信的唯一传输方法是长轮询,但对我来说它并不完全令人满意。预先感谢您的帮助!
中间件顺序很重要。
if (turnOnWebsockets)
app.UseWebSockets();
需要在 UseOcelot
调用之前发生。
例子
像这样的东西应该适合你
.Configure(async app =>
{
app.UseCors(cors =>
{
cors.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed(x => true)
.AllowCredentials();
});
if (turnOnWebsockets)
app.UseWebSockets();
app.UseOcelot().Wait();
备注
AFAIK async Configure
目前在 ASP.NET Core 中不受支持。使用 .Wait()
通常是不受欢迎的,但在这种情况下它是必需的,也是 Ocelot documentation 鼓励的方式。