.Net 8 Grpc CLient не может установить соединение http/2. Исключение:

Хорошо, я не понимаю, что мне нужно делать. У меня есть клиент WPF, который я написал в .net 8, который должен подключаться к серверу Go gRPC, но каждый раз, когда я пытаюсь подключиться, я получение следующего исключения

 [ALERT] Connection Status: Connection error: Status(StatusCode = "Internal", Detail = "Error starting gRPC call. HttpRequestException: Requesting HTTP version 2.0 with version policy RequestVersionOrHigher while unable to establish HTTP/2 connection.", DebugException = "System.Net.Http.HttpRequestException: Requesting HTTP version 2.0 with version policy RequestVersionOrHigher while unable to establish HTTP/2 connection.")

Проблема в том, что когда я подключаю соединение Shark, я ясно вижу, что рукопожатие TLS 1.2 завершается И оно использует HTTP2.

Я вижу, что позже появляется зашифрованное предупреждение, но это происходит через несколько секунд после создания исключения, поэтому я не знаю, почему.

в любом случае я подумал, что это может быть самозаверяющий сертификат, поэтому я добавил в mainwindow()

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

и для хороших мер на всякий случай AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

моя функция канала инициализации выглядит так

        internal async Task InitializeChannel(string ip)
        {
            Console.WriteLine("Initializing Channel with IP: " + ip);
            Logger.Log("Initializing Channel with IP: " + ip, 1);

            if (!string.IsNullOrEmpty(ip))
            {
                var parts = ip.Split(':');
                if (parts.Length == 2 && int.TryParse(parts[1], out int port))
                {
                    try
                    {

                        
                        var httpClientHandler = new HttpClientHandler
                        {
                            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
                            {
                                return true; 
                            },
                            SslProtocols = System.Security.Authentication.SslProtocols.Tls12
                            
                        };


                        var loggingHandler = new LoggingHandler(httpClientHandler);

                        
                        var httpClient = new HttpClient(loggingHandler)
                        {
                            DefaultRequestVersion =  HttpVersion.Version20,
                            DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher
                        };

                        Logger.Log("Creating GrpcChannel", 0);

                        // Create the GrpcChannel using the HttpClient
                        Channel = GrpcChannel.ForAddress($"https://{parts[0]}:{port}", new GrpcChannelOptions
                        {
                            HttpClient = httpClient
                        });


                    }
                    catch (Exception ex)
                    {
                        Logger.Log($"Exception in InitializeChannel: {ex.Message}", 3);
                        throw;
                    }
                }
                else
                {
                    TeamServerStatus = "Invalid IP format";
                    Logger.Log("Invalid IP format", 2);
                }
            }
            else
            {
                Logger.Log("IP is null or empty", 2);
            }
        }

        // Define the custom HttpMessageHandler with logging
        public class LoggingHandler : DelegatingHandler
        {
            public LoggingHandler(HttpMessageHandler innerHandler)
                : base(innerHandler)
            {
            }

            protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
            {
                // Log the request details
                Logger.Log($"Request: {request.Method} {request.RequestUri}", 0);
                Logger.Log($"Request Headers: {request.Headers}", 0);
                Logger.Log($"Request Version: {request.Version}", 0);

                // Send the request
                var response = await base.SendAsync(request, cancellationToken);

                // Log the response details
                Logger.Log($"Response: {response.StatusCode}", 0);
                Logger.Log($"Response Headers: {response.Headers}", 0);
                Logger.Log($"Response Version: {response.Version}", 0);

                return response;
            }
        }

и вот журнал, который он создает, когда я пытаюсь подключиться

[06/24 08:54] [Debug] TS Connect initatied
[06/24 08:54] [Debug] Attempted to connect to TS
[06/24 08:54] [Info] Initializing Channel with IP: 127.0.0.1:5001
[06/24 08:54] [Debug] Creating GrpcChannel
[06/24 08:54] [Info] Attempting to connect to Team Server at: 127.0.0.1:5001
[06/24 08:54] [Debug] Request: POST https://127.0.0.1:5001/App.Auth/ConnectToTeamServer
[06/24 08:54] [Debug] Request Headers: User-Agent: grpc-dotnet/2.59.0 (.NET 8.0.0; CLR 8.0.0; net8.0; windows; x64)
TE: trailers
grpc-accept-encoding: identity,gzip,deflate

[06/24 08:54] [Debug] Request Version: 2.0
[06/24 08:54] [Critical] Connection error: Status(StatusCode = "Internal", Detail = "Error starting gRPC call. HttpRequestException: Requesting HTTP version 2.0 with version policy RequestVersionOrHigher while unable to establish HTTP/2 connection.", DebugException = "System.Net.Http.HttpRequestException: Requesting HTTP version 2.0 with version policy RequestVersionOrHigher while unable to establish HTTP/2 connection.")
[06/24 08:54] [Debug] Connection Status recived: Connection error: Status(StatusCode = "Internal", Detail = "Error starting gRPC call. HttpRequestException: Requesting HTTP version 2.0 with version policy RequestVersionOrHigher while unable to establish HTTP/2 connection.", DebugException = "System.Net.Http.HttpRequestException: Requesting HTTP version 2.0 with version policy RequestVersionOrHigher while unable to establish HTTP/2 connection."

Насколько я могу судить, на самом деле это не http2? но это не имеет смысла, поскольку у него есть ALPN. Любая помощь будет принята с благодарностью

Как включить TLS в gRPC-клиенте и сервере : 2
Как включить TLS в gRPC-клиенте и сервере : 2
Здравствуйте! 🙏🏻 Надеюсь, у вас все хорошо и добро пожаловать в мой блог.
GRPC на Android с использованием TLS
GRPC на Android с использованием TLS
GRPC - это относительно новая концепция взаимодействия между клиентом и сервером, но не более.
0
0
164
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Так получилось, что это все-таки была сторона Го. После долгих исследований выяснилось, что по умолчанию сервер не рекламировал ALPN, поэтому на этапе согласования произошел сбой, несмотря на то, что он был жестко настроен на использование HTTP2. Итак, похоже, что клиент .Net отправлял ClienttHello с расширением h2 ALPN, но ServerHello сервера GO не включал свой ALPN в ответ. Поскольку в этом отношении согласование не удалось, gRPC выдаст ошибку, поскольку не сможет установить соединение через Http2. Это очень похоже на то, что произошло бы, если бы сертификаты также не были приняты, поэтому я предположил, что это основано на сертификате, но мы видим, что сертификат действителен из Wireshark, поскольку он прошел проверку TLS, поэтому что-то еще не удалось.

TL;DR исправление заключается в том, что вы должны заставить конфигурацию TLS сервера Go включить ALPN «h2» в сборку, что-то вроде этого

    tlsConfig := &tls.Config{
        Certificates: []tls.Certificate{
            cert,
        },
        NextProtos: []string{"h2"},
    }
return tlsConfig, nil
}

надеюсь, это поможет любому, кто тоже столкнулся с этой глупой проблемой.

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

Можно ли использовать .NET 8 для службы Windows?
(C#/.NET 8.0) Почему я не могу получать, а затем отправлять данные из UdpClients, созданных и используемых в отдельных потоках?
Некоторые журналы функций Azure отсутствуют в Application Insights
Функции Azure + .NET8 (изолированный режим) + OIDC — как проверить токен доступа, полученный в заголовке каждого запроса к моей функции Azure?
Цветные значки панели инструментов появляются в свойстве Shell.ForegroundColor на iOS – (MAUI)
Функция службы C# Blazor .net 8 для доступа к изменениям в основных макетах @body и их применения к компоненту в основном макете
Az funcappPublish .net8 Изолированное нарушение настроек среды выполнения конфигурации Azure при синхронизации
.NET 8 Blazor Server — авторизация ролей с проверкой подлинности Windows
System.IO.FileLoadException в Ubuntu 24.04 при запуске веб-приложения .Net 8 или blazorapp
Я использую VS Code, как мне плавно перейти с ASP.NET Core из .NET 7 на .NET 8?