gRPC 的 HTTP2 .Net Framework 问题

HTTP2 .Net Framework issues with gRPC

我需要使用 gRPC 进行双向流式传输,其中客户端是 .Net Framework 项目,由于遗留问题,无法升级到 .NET5+。

阅读微软文档时,我发现应该使用 WinHttpHandler (https://docs.microsoft.com/en-us/aspnet/core/grpc/netstandard?view=aspnetcore-5.0)。

但是我在使用 SSL 时似乎遇到了这个设置的问题,有人对如何解决这个问题有什么建议吗?

我收到以下错误:

"InvalidOperationException: SslCredentials with non-null arguments is not supported by GrpcChannel. GrpcChannel uses HttpClient to make gRPC calls and HttpClient automatically loads root certificates from the operating system certificate store. Client certificates should be configured on HttpClient. See https://aka.ms/aspnet/grpc/certauth for details."

我的服务器设置如下:

let cacert = File.ReadAllText(@"ca.crt");
let servercert = File.ReadAllText(@"server.crt");
let serverkey = File.ReadAllText(@"server.key");

let certificatePair = new KeyCertificatePair(servercert, serverkey);
let certList = new System.Collections.Generic.List<KeyCertificatePair>()
    certList.Add(certificatePair)
let server = new Server()
    server.Services.Add(EventSubscriberService.EventSubscriberServiceMethodBinder.BindService(new EventSubscriber()))
    server.Ports.Add(new ServerPort("localhost", 5001,SslServerCredentials(certList,cacert,false))) 
    |> ignore'''

并且客户端使用此设置:

let cacert = File.ReadAllText(@"ca.crt");
let clientcert = File.ReadAllText(@"client.crt");
let clientkey = File.ReadAllText(@"client.key");
let ssl = new SslCredentials(cacert, new KeyCertificatePair(clientcert, clientkey))

let channelOptions = GrpcChannelOptions()
channelOptions.HttpHandler <- new WinHttpHandler()    
channelOptions.Credentials <- ssl


let channel = GrpcChannel.ForAddress("http://127.0.0.1:5001",channelOptions)

它是用 F# 编写的,但类似于此 C# 代码,如果参考有助于提高可读性。

可能以下几行(草稿)应该起作用:

open System.Net.Http
open Grpc.Net.Client
open System.Security.Cryptography.X509Certificates

let clientCert = new X509Certificate() // create according to your needs
let handler = new HttpClientHandler()
handler.ClientCertificates.Add(clientCert) |> ignore
// insecure, check your custom server cert
handler.ServerCertificateCustomValidationCallback <- fun msg cert chain e -> true
let client = new HttpClient(handler)
let channelOptions = GrpcChannelOptions(HttpClient = client)
let channel = GrpcChannel.ForAddress("http://127.0.0.1:5001", channelOptions)