Как заставить.net HttpClient использовать http 2.0?

У меня есть веб-API asp.net, размещенный на IIS 10 (Windows Server 2016). Когда я делаю 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

Тем не менее, когда 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));
    }
}

Я вижу следующее 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

Как я могу заставить клиента.net использовать HTTP/2.0?

3 ответа

Решение

HttpClient пока не поддерживает HTTP/2. Он будет доступен в следующем выпуске (кодовое название KATANA). Вот ссылка на их исходный код для следующего выпуска.

До этого вы могли бы реализовать свой собственный HttpMessageHandler объект, который реализует HTTP/2 и передает его HttpClientконструктор (вы, вероятно, можете использовать их исходный код из KATANA).

1. Убедитесь, что вы используете последнюю версию Windows 10.

2.Установите WinHttpHandler:

Install-Package System.Net.Http.WinHttpHandler

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);
    }
}

4. Передать выше обработчик в конструктор HttpClient

using (var httpClient = new HttpClient(new Http2CustomHandler()))
{
      // your custom code
}

В дополнении к WinHttpHandler( как описано в ответе Шавиндера Сехона), .NET Core 3.0 включает поддержку HTTP/2 по умолчанию SocketsHttpHandler( #30740). Поскольку по умолчанию за пределами UWP по- прежнему используется HTTP / 1.1, 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));
    }
}

Или для всех запросов с помощью настраиваемого 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);
    }
}

который может делегировать SocketsHttpHandler, WinHttpHandler, или любой другой 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));
    }
}
``

Похоже, что HTTP / 2 будет поддерживаться в клиентских вызовах C# в.NET 4.6.2

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

Поддержка HTTP / 2 (Windows 10)

HTTP / 2 - это новая версия протокола HTTP, которая обеспечивает намного лучшее использование соединения (меньше циклов между клиентом и сервером), что приводит к снижению загрузки веб-страниц с задержкой для пользователей. Веб-страницы (в отличие от сервисов) получают наибольшую выгоду от HTTP/2, поскольку протокол оптимизируется для нескольких артефактов, запрашиваемых как часть единого опыта. Поддержка HTTP / 2 была добавлена ​​в ASP.NET в.NET Framework 4.6. Поскольку сетевые функции существуют на нескольких уровнях, новые функции требовались в Windows, IIS и ASP.NET для включения HTTP / 2. Вы должны работать в Windows 10, чтобы использовать HTTP / 2 с ASP.NET.

HTTP / 2 также поддерживается и включен по умолчанию для приложений Windows 10 Universal Windows Platform (UWP), использующих API-интерфейс System.Net.Http.HttpClient.

Другие вопросы по тегам