如何使.net HttpClient使用http 2.0?

tcb*_*tcb 17 c# asp.net http http2 iis-10

我在IIS 10(Windows Server 2016)上托管了一个asp.net web api.当我GET从Microsoft Edge浏览器发出请求时,我看到它HTTP 2.0在IIS日志中使用

2015-09-20 21:57:59 100.76.48.17 GET /RestController/Native - 443 - 73.181.195.76 HTTP/2.0 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/42.0.2311.135+Safari/537.36+Edge/12.10240 - 200 0 0 7299
Run Code Online (Sandbox Code Playgroud)

但是,当GET通过.net 4.6客户端发出请求时,如下所示,

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("https://myapp.cloudapp.net/");

    HttpResponseMessage response = await client.GetAsync("RestController/Native");
    if (response.IsSuccessStatusCode)
    {
        await response.Content.CopyToAsync(new MemoryStream(buffer));
    }
}
Run Code Online (Sandbox Code Playgroud)

HTTP 1.1在服务器日志中看到以下日志

2015-09-20 20:57:41 100.76.48.17 GET /RestController/Native - 443 - 131.107.160.196 HTTP/1.1 - - 200 0 0 707
Run Code Online (Sandbox Code Playgroud)

如何让.net客户端使用HTTP/2.0?

Sha*_*hon 26

1.确保您使用的是最新版本的Windows 10.

2.安装WinHttpHandler:

Install-Package System.Net.Http.WinHttpHandler
Run Code Online (Sandbox Code Playgroud)

3.扩展WinHttpHandler以添加http2.0支持:

public class Http2CustomHandler : WinHttpHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        request.Version = new Version("2.0");
        return base.SendAsync(request, cancellationToken);
    }
}
Run Code Online (Sandbox Code Playgroud)

4.通过上面的HttpClient构造函数处理程序

using (var httpClient = new HttpClient(new Http2CustomHandler()))
{
      // your custom code
}
Run Code Online (Sandbox Code Playgroud)


Rac*_*lan 8

HttpClient还不支持HTTP/2.它将在下一版本中提供(代号KATANA).这是下一个版本的源代码链接.

到那时,您可以实现自己的HttpMessageHandler实现HTTP/2 的对象并将其传递给HttpClient构造函数(您可能可以使用来自KATANA的源代码).


Kev*_*oid 8

除此之外WinHttpHandler如 Shawinder Sekhon 的回答中所述),.NET Core 3.0默认包含 HTTP/2 支持SocketsHttpHandler#30740)。由于HTTP/1.1 仍然是默认值,因此必须通过设置更改默认值HttpClient.DefaultRequestVersion,或者Version必须在每次请求时更改默认值。版本可以在创建请求消息时设置:

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("https://myapp.cloudapp.net/");

    HttpResponseMessage response = await client.SendAsync(
        new HttpRequestMessage(HttpMethod.Get, "RestController/Native")
        {
            Version = HttpVersion.Version20,
        });
    if (response.IsSuccessStatusCode)
    {
        await response.Content.CopyToAsync(new MemoryStream(buffer));
    }
}
Run Code Online (Sandbox Code Playgroud)

或者使用自定义的HttpMessageHandler,例如:

public class ForceHttp2Handler : DelegatingHandler
{
    public ForceHttp2Handler(HttpMessageHandler innerHandler)
        : base(innerHandler)
    {
    }

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Version = HttpVersion.Version20;
        return base.SendAsync(request, cancellationToken);
    }
}
Run Code Online (Sandbox Code Playgroud)

它可以委托给SocketsHttpHandlerWinHttpHandler或任何其他HttpMessageHandler支持 HTTP/2 的对象:

using (var client = new HttpClient(new ForceHttp2Handler(new SocketsHttpHandler())))
{
    client.BaseAddress = new Uri("https://myapp.cloudapp.net/");

    HttpResponseMessage response = await client.GetAsync("RestController/Native");
    if (response.IsSuccessStatusCode)
    {
        await response.Content.CopyToAsync(new MemoryStream(buffer));
    }
}
Run Code Online (Sandbox Code Playgroud)


Oli*_*ver 5

.NET 4.6.2 的 C# 客户端调用似乎支持 HTTP/2

https://msdn.microsoft.com/en-us/library/ms171868(v=vs.110).aspx

HTTP/2 支持(Windows 10)

HTTP/2 是 HTTP 协议的新版本,它提供了更好的连接利用率(客户端和服务器之间的往返次数更少),从而为用户提供了更低的网页加载延迟。网页(相对于服务)从 HTTP/2 中获益最多,因为该协议针对作为单一体验的一部分请求的多个工件进行了优化。HTTP/2 支持已添加到 .NET Framework 4.6 中的 ASP.NET。由于网络功能存在于多个层,因此在 Windows、IIS 和 ASP.NET 中需要新功能来启用 HTTP/2。您必须在 Windows 10 上运行才能将 HTTP/2 与 ASP.NET 一起使用。

对于使用 System.Net.Http.HttpClient API 的 Windows 10 通用 Windows 平台 (UWP) 应用,HTTP/2 也受支持并默认启用。

  • 看到这条评论:`要使用 HTTP/2 协议支持,你必须使用 .NET Core。您还必须使用受支持的 Windows 10 版本。并且您需要手动指定 HttpRequestMessage.Version = new Version(2,0); 您还可以使用单独的 System.Net.Http.WinHttpHandler 包,它为 HttpClient 提供备用处理程序。您需要创建该 WinHttpHandler 并将其传递给 HttpClient 的构造函数。此处的 .NET Core .NET Framework` 均支持此 WinHttpHandler 包:https://github.com/dotnet/corefx/issues/4870 (2认同)