c# - Ocelot 不将 websocket 传递给微服务

标签 c# .net signalr ocelot

我正在尝试使用 Ocelot 作为代理连接到 SignalR 集线器。 SignalR 插入微服务中,该网关通过 Websocket 流量传递。通过 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;
}

如何将 Websocket 与 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 所鼓励的方式。也是如此。

关于c# - Ocelot 不将 websocket 传递给微服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63472028/

相关文章:

c# - 使用 HTMLAgilityPack c# 按类名删除元素

signalr - Microsoft.AspNet.SignalR.Core 和 Microsoft.AspNet.SignalR.Owin 中的重复定义

c# - 带有 TextBlock 的 BulletDecorator 不显示 Unicode 字符

c# - 创建/更新/删除分层数据的正确方法

c# - 如何将对象添加到包含另一个列表的列表

c# - 在没有对话框的情况下以编程方式保存 MHT

c# - 我们如何在asp.net mvc-6核心中实现 "Bell Notification"

javascript - 连接尚未完全初始化

c# - 在C#中将文本数据转换为百分比

c# - 如何等到值添加到 ConcurrentDictionary 或发生超时?