Search code examples
docker-composesignalraspnetboilerplateocelot

SignalR not working with Ocelot API Gateway


I am using ASP.Net boilerplate architecture for my project and using Ocelot API Gateway.

Without using gateway, I can access signalr successfully from my angular App.

But when I try to access signalr through API Gateway, All requests stay in pending state and get this error docker error

Following is my configuration.json changes for signalr configuration.json

And following change I made in the Startup.cs file of the gateway.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        if (_ocelotSwaggerConfiguration.IsSwaggerEnabled)
        {
            app.UseSwaggerForOcelotUI(Configuration);
        }

        // Enable ReDoc Documentation
        app.UseReDoc(c =>
        {
            c.DocumentTitle = "AI API";
            c.SpecUrl = "/swagger/docs/v1/pitch-ai";
            c.RoutePrefix = string.Empty;
            c.IndexStream = () => Assembly.GetExecutingAssembly()
                .GetManifestResourceStream("AI.Api.Gateway.api_docs.ui.index.html");
            c.HeadContent = GetRedocHeaderContent();
        });

        app.UseAuthentication();
        app.UseStaticFiles();

        app.UseMetricServer();
        app.UseMiddleware<ResponseMetricMiddleware>();
        app.UseHttpMetrics();
        app.UseWebSockets();
        app.UseHealthChecks("/ready", new HealthCheckOptions
        {
            Predicate = r => r.Tags.Contains("services")
        });

        app.Map("/switch", appBuilder =>
        {
            appBuilder.Run(async context =>
            {
                running = !running;
                await context.Response.WriteAsync($"{Environment.MachineName} running {running}");
            });
        });

        app.UseHealthChecks("/health", new HealthCheckOptions
        {
            Predicate = r => r.Name.Contains("health")
        });

        app.UseMetricsAllEndpoints();
        
        app.UseOcelot().ContinueWith(t => Log.Error(t.Exception.Message, t.Exception), System.Threading.Tasks.TaskContinuationOptions.OnlyOnFaulted);
    }

Solution

  • The following change works for me. Applied following changes in configuration.json

    {
          "DownstreamPathTemplate": "/{everything}",
          "DownstreamScheme": "ws",
          "UpstreamPathTemplate": "/{everything}",
          "UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ],
          "SwaggerKey": "ai",
          "ServiceName": "ai-web-api",
          "RateLimitOptions": {
            "ClientWhitelist": [],
            "EnableRateLimiting": true,
            "Period": "1s",
            "PeriodTimespan": 1,
            "Limit": 10
          }
        }
    

    Also, I found that I don't need Microsoft.AspNetCore.SignalR.Client in gateway project.

    And I moved app.UseWebSockets(); before app.UseOcelot() in Startup.cs