Хорошо, я не понимаю, что мне нужно делать. У меня есть клиент 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. Любая помощь будет принята с благодарностью


Так получилось, что это все-таки была сторона Го. После долгих исследований выяснилось, что по умолчанию сервер не рекламировал 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
}
надеюсь, это поможет любому, кто тоже столкнулся с этой глупой проблемой.