grpc-dotnet
grpc-dotnet copied to clipboard
Testing for a valid endpoint on a duplex connection
I need to test that an endpoint is valid for a duplex stream connection without sending a message. I have figured out a way to do it, but it doesn't work for every scenario.
`
var saCerts = CertificateValidation.CreateTrustedRootCollection( certificateAthorities );
var options = new GrpcChannelOptions();
if( url.StartsWith( "https" ) )
{
var handler = new SocketsHttpHandler();
handler.SslOptions = new SslClientAuthenticationOptions
{
RemoteCertificateValidationCallback = CertificateValidation.CreateRemoteCertificateValidationCallback( saCerts ),
ClientCertificates = new X509CertificateCollection()
};
handler.SslOptions.ClientCertificates.Add( new X509Certificate2( /*Certificate*/ ) );
options.HttpHandler = handler;
}
channel = GrpcChannel.ForAddress( url, options );
//This is how I found to test a connection
channel.ConnectAsync();
var task = channel.WaitForStateChangedAsync( ConnectivityState.Connecting );
task.Wait(5000);
if( channel.State != ConnectivityState.Ready )
throw new Exception( $"Could not connect to URL: {url}." );
//End connection test
var client = new MyMessage.MyMessageClient( channel );
call = client.Stream( null, null, cancellationSource.Token );
`
Using ConnectAsync works when there is no endpoint at all. It also works (through the task timeout) when there is something at the endpoint, but not one I can connect to.
However, in the instance the url is correct, but the server port is secure and the used url is not secure (or vice versa), channel.ConnectAsync() works, and the channel state becomes ConnectivityState.Ready, despite the mismatch in security.
The only way I could figure out how to test if the endpoint is completely valid is to send a message. However, for reasons outside of my control, this is not going to work for me.
So my questions are: Is ConnectAsync the right way to test? And how do you check if the endpoint is completely valid without sending a message?
Any help is appreciated.
However, in the instance the url is correct, but the server port is secure and the used url is not secure (or vice versa), channel.ConnectAsync() works, and the channel state becomes ConnectivityState.Ready, despite the mismatch in security.
This is a known limitation in grpc-dotnet. It only tests that the TCP connection is healthy. TLS only becomes involved when a message is sent.
Thank you James for the reply. Forgive my ignorance about all of this, but isn't testing for the valid endpoint something that is done in Grpc.Core before sending a message? Is testing the connection without sending a message something that can be or is planned to be implemented in the future for this aspnetcore version?
I'd like to support it, but it requires changes in the .NET networking layer.