Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2ConnectionErrorException - PullRequest
1 голос
/ 02 июля 2019

У меня есть следующее исключение

Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2ConnectionErrorException: Ошибка соединения HTTP / 2 (PROTOCOL_ERROR): неверное соединение HTTP / 2 предисловие.

Я опишу мои условия. У меня очень простой проект grpc .Net Cor e, и я хочу создать конечную точку HTTP .

Вот Startup.cs

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(options => options.EnableEndpointRouting = false);
        services.AddGrpc();

        services.AddHttpClient<IAnalyticApiAsker, AnalyticApiAsker>();

        // db context
        services.AddSingleton<IApplicationMongoContext, ApplicationMongoContext>();

        // repos
        services.AddTransient<IWorkspacesRepo, WorkspaceRepo>();
        services.AddTransient<IApplicationRepo, ApplicationRepo>();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            // Communication with gRPC endpoints must be made through a gRPC client.
            // To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909
            endpoints.MapGrpcService<ApplicationsService>();
            endpoints.MapGrpcService<WorkspacesService>();
        });

        // I think I have to use this middleware for get http endpoints ability ?? Right? 
        app.UseMvc();
    }
}

И Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

launchSettings.json

{
  "profiles": {
    "Dashboard": {
      "commandName": "Project",
      "launchBrowser": false,
      "applicationUrl": "http://*:50053",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Local"
      }
    }
  }
}

Для конечной точки у меня есть следующий контроллер:

public class HealthController : Controller
{ 
    [Route("/healthcheck")]
    [HttpGet]
    public IActionResult Index()
    {
        return Ok(new
        {
            status = "ok",
            description = "works"
        });
    }
}

Но когда я запрашиваю у браузера URL моего приложения http://localhost:50053/healthcheck, у меня возникает это исключение похоже, Kestrel настроен только для http2. Если это правда, как включить обработку HTTP?

Обновление

Хорошо, после некоторых исследований я понял следующее. Невозможно включить обработку обоих типов протоколов: grpc (который работает с HTTP 2) и обычный http1 одновременно. Я прав?

Я изменил свой Startapp.cs на:

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureKestrel(options =>
            {
                options.ListenLocalhost(50053, listenOptions =>
                {
                    listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
                });
            })
            .UseStartup<Startup>();

HttpProtocols.Http1AndHttp2 это свойство имеет вариант для каждого типа HTTP (Http1, Http, Http1AndHttp2). Но это не работает для GRPC. Я думаю, что это происходит из-за того, использовать ли http1 для GRPC или http2. И я не знаю, как это настроить.

Итак, listenOptions.Protocols = HttpProtocols.Http1 - работает для сети, listenOptions.Protocols = HttpProtocols.Http2 - работает для GRPC и listenOptions.Protocols = HttpProtocols.Http1AndHttp2 - работает для сети.

Обновление 2

Я не уверен, отвечает ли он или нет, но я решил задачу с помощью следующей модификации Program.cs:

    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureKestrel(options =>
            {
                options.ListenLocalhost(80, listenOptions =>
                {
                    listenOptions.Protocols = HttpProtocols.Http1;
                });

                options.ListenLocalhost(50053, listenOptions =>
                {
                    listenOptions.Protocols = HttpProtocols.Http2;
                });
            })
            .UseStartup<Startup>();
}

Теперь я могу работать с http1 и http2. Но теперь у меня новая проблема, она работает только на локальном хосте.

1 Ответ

0 голосов
/ 02 июля 2019

Хорошо, я решил это с помощью следующей модификации Program.cs:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureKestrel(options =>
            {
                options.ListenAnyIP(80, listenOptions =>
                {
                    listenOptions.Protocols = HttpProtocols.Http1;
                });

                options.ListenAnyIP(50053, listenOptions =>
                {
                    listenOptions.Protocols = HttpProtocols.Http2;
                });
            })
            .UseStartup<Startup>();
}

Теперь я могу работать с GRPC и http1 одновременно, и соединение разрешено для любого IP.

Надеюсь, это будет полезно для тех, кто добавит http1 в настроенный GRPC проект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...