在 .Net 中使用 HTTP 2 和 HttpClient [英] Use HTTP 2 with HttpClient in .Net

查看:243
本文介绍了在 .Net 中使用 HTTP 2 和 HttpClient的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 HTTP 2.0 请求数据.我正在使用 .Net Core 2.2 中的 HttpClient.我在 Windows 10 上,但将在 Linux 上运行.问题是响应中的版本似乎总是1.1".我做错了什么?

I'm trying to request data over HTTP 2.0. I'm using the HttpClient from .Net Core 2.2. I'm on Windows 10 but will run on Linux in production. The problem is that the version on the response seems to always be "1.1". What I am doing wrong?

using (var client = new HttpClient())
{
    using (var request = new HttpRequestMessage(new HttpMethod("GET"),
    "https://duckduckgo.com/"
    ))
    {
        request.Version = new Version(2, 0);
        var response = await client.SendAsync(request);

        Console.WriteLine(response.Version);
    }
}

推荐答案

更新 - .NET Core 3.0

.NET Core 3.0 现在 支持 HTTP/2.以下代码将打印 2.0 :

.NET Core 3.0 now supports HTTP/2. The following code will print 2.0 :

var client = new HttpClient();

var req = new HttpRequestMessage(HttpMethod.Get, "https://http2.akamai.com/demo"){
             Version = new Version(2, 0) 
             };

var x = await client.SendAsync(req);
var version = x.Version;

Console.WriteLine(version);

原答案

不能在 .NET Core 2.1 或 2.2 中将 HTTP/2 与 HttpClient 一起使用,即使您在请求中明确设置了版本.您必须显式配置 .NET Core 以使用 .NET Core 2.0 附带的 HttpClientHandler 实例,方法是使用 :

You can't use HTTP/2 with HttpClient in .NET Core 2.1 or 2.2, even if you explicitly set the version in the request. You'll have to explicitly configure .NET Core to use the old HttpClientHandler instance that came with .NET Core 2.0, either by setting an App Context switch with :

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

或者通过将 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER 环境变量设置为 0false.

Or by setting the DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER environment variable to 0 or false.

this Github issue 中的讨论表明,计划为 .NET 核心 3.0.在 Microsoft Connect 2018 上发布的 3.0 Preview 1 尚不支持 HTTP/2.

The discussion in this Github issue shows that HTTP/2 support is planned for .NET Core 3.0. The 3.0 Preview 1 released at Microsoft Connect 2018 doesn't support HTTP/2 yet.

使用的 HttpClientHandler 最多支持 .NET Core 2.0 支持的 HTTP/2.以下代码将在面向 Core 2.0 的项目中返回 2.0 :

The HttpClientHandler used up to .NET Core 2.0 supported HTTP/2. The following code will return 2.0 in a project that targets Core 2.0 :

var client = new HttpClient();

var req = new HttpRequestMessage(HttpMethod.Get, "https://http2.akamai.com/demo")
{
    Version = new Version(2, 0)
};

var x = await client.SendAsync(req);
var version = x.Version;

Console.WriteLine(version);

如果您更改目标运行时,请确保彻底清理您的项目 - 删除 binobj 所有目标文件,或者您最终可能会像我一样运行错误的运行时.

Just make sure you thoroughly clean your project if you change the target runtime - delete bin, obj and all target files, or you may end up running with the wrong runtime as I did.

在 2.1 中,默认添加了一个新的、速度更快的 SocketsHttpClientHandler.新处理程序尚不支持 HTTP/2.相同的代码将返回 1.1 作为协议版本.

In 2.1 a new, far faster SocketsHttpClientHandler was added as a default. The new handler doesn't support HTTP/2 yet. The same code will return 1.1 as the protocol version.

如果在创建 HttpClient 之前设置了应用上下文切换,则使用 HTTP/2.此代码将返回 2.0.有趣的是,无需指定 HTTP 版本.当 HTTP/2 可用时,协商实际的协议版本.即使未指定版本,Akamai URL 和 https://www.google.com 也将使用 HTTP/2:

If the app context switch is set before creating the HttpClient though, HTTP/2 is used. This code will return 2.0. Interestingly, there's no need to specify the HTTP version. When HTTP/2 is available, the actual protocol version is negotiated. Both the Akamai URL and https://www.google.com will use HTTP/2 even though the version wasn't specified:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
var client = new HttpClient();

var req = new HttpRequestMessage(HttpMethod.Get, "https://http2.akamai.com/demo");
var x = await client.SendAsync(req);

var version = x.Version;

开关和环境变量在.NET Core 2.1 SDK 预览版 2:

我们对 .NET Core 2.1 中的套接字进行了重大改进.套接字是传出和传入网络通信的基础..NET Core 2.1 中更高级别的网络 API,包括 HttpClient 和 Kestrel,现在基于 .NET 套接字.在早期版本中,这些更高级别的 API 基于本机网络实现.

Sockets Performance and SocketsHttpHandler

We made major improvements to sockets in .NET Core 2.1. Sockets are the basis of both outgoing and incoming networking communication. The higher-level networking APIs in .NET Core 2.1, including HttpClient and Kestrel, are now based on .NET sockets. In earlier versions, these higher-level APIs were based on native networking implementations.

...

您可以使用以下机制之一来配置进程以使用较旧的 HttpClientHandler:

You can use one of the following mechanisms to configure a process to use the older HttpClientHandler:

从代码中,使用 AppContext 类:

From code, use the AppContext class:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

AppContext 开关也可以通过配置文件设置.

The AppContext switch can also be set by config file.

同样可以通过环境变量 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER 实现.要选择退出,请将值设置为 false 或 0.

The same can be achieved via the environment variable DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER. To opt out, set the value to either false or 0.

这篇关于在 .Net 中使用 HTTP 2 和 HttpClient的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆