首页 > 解决方案 > 如何通过普通 http 在 C# Kestrel Web 服务器中启用 http2?

问题描述

我如何(是否有可能)在 C# Kestrel Web 服务器中通过普通 http 启用 http2?所有 Microsoft 文档都表明需要 https/TLS,但我有将在负载均衡器或 nginx 后面运行的服务,因此不需要第二层 https。官方的 http2 规范表明 https 不是必需的。

标签: c#http

解决方案


使用未加密 http2 的场景是负载均衡器、代理等。

您必须做三件事才能在未加密的通道上使用 http2。

设置 Kestrel 在您的服务器上使用 http2:

builder.ConfigureWebHostDefaults((webBuilder) =>
{
    // this will keep your other end points settings such as --urls parameter
    webBuilder.ConfigureKestrel((options) =>
    {
        // trying to use Http1AndHttp2 causes http2 connections to fail with invalid protocol error
        // according to Microsoft dual http version mode not supported in unencrypted scenario: https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0
        options.ConfigureEndpointDefaults(lo => lo.Protocols = HttpProtocols.Http2);
    });
});

对于 .net 5+,创建您的HttpClient实例,然后创建一条消息并指定版本:

var request = new HttpRequestMessage(HttpMethod.Get, uri)
{
    Version = HttpVersion.Version20,
    VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher
};

对于 .net core 3.1 及更早版本,设置一个标志以启用未加密的 http2。然后,当您创建 时HttpClient,请指定版本:

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
var client = new HttpClient { BaseAddress = new Uri(baseUrl), DefaultRequestVersion = new Version(2, 0) };

如果您需要在完全未加密的主机上同时支持 http1 和 http2,那么您需要监听两个端口,每个端口对应一个 http 版本。然后,您的负载均衡器或代理将需要处理 http 版本并定向到适当的端口。

您不会在浏览器上看到 http2,并且可能会收到协议错误,因此在这些情况下,您可以将 http1 协议指令仅用于开发环境。不理想,但它至少可以让您在本地进行测试。


推荐阅读