Вы не можете использовать HTTP / 2 с HttpClient в .NET Core 2.1 или 2.2 , даже если вы явно указали версию в запросе.Вам нужно будет явно настроить .NET Core для использования старого экземпляра HttpClientHandler, поставляемого с .NET Core 2.0, либо установив переключатель контекста приложения с помощью:
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
Илиустановка переменной среды DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER
на 0
или false
.
Обсуждение в этой проблемы Github показывает, что поддержка HTTP / 2 запланирована для .NET Core 3.0.Версия 3.0 Preview 1, выпущенная в Microsoft Connect 2018, пока не поддерживает HTTP / 2.
HttpClientHandler, используемый до .NET Core 2.0, поддерживал HTTP / 2.Следующий код вернет 2.0
в проекте, ориентированном на 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);
Просто убедитесь, что вы тщательно очистили свой проект, если изменили целевую среду выполнения - удалите bin
, obj
и все целевые файлы, или вы можете работать с неправильной средой выполнения, как я.
В 2.1 по умолчанию был добавлен новый, гораздо более быстрый SocketsHttpClientHandler.Новый обработчик пока не поддерживает HTTP / 2.Тот же код вернет 1.1
в качестве версии протокола.
Если перед созданием HttpClient установлен переключатель контекста приложения, используется HTTP / 2.Этот код вернет 2.0
.Интересно, что нет необходимости указывать версию HTTP.Когда HTTP / 2 доступен, фактическая версия протокола согласовывается.URL-адрес Akamai и https://www.google.com
будут использовать HTTP / 2, хотя версия не указана:
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.1SDK Preview 2 :
Производительность сокетов и сокетыHttpHandler
Мы внесли значительные улучшения в сокеты в .NET Core 2.1.Сокеты являются основой как исходящей, так и входящей сетевой связи.Сетевые API более высокого уровня в .NET Core 2.1, включая HttpClient и Kestrel, теперь основаны на сокетах .NET.В более ранних версиях эти высокоуровневые API-интерфейсы основывались на собственных сетевых реализациях.
...
Вы можете использовать один из следующих механизмов для настройки процесса на использование более старого HttpClientHandler:
Из кода используйте класс AppContext:
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
Переключатель AppContext также можно установить с помощью файла конфигурации.
То же самое можно сделать с помощью переменной окружения DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER.Чтобы отказаться, установите значение либо false, либо 0.