Our WPF .NET 6 app is a gRPC server using Grpc.Core NUGET packages. I have not migrated to the new Grpc.NET implementation. when I do, hopefully it doesn't mandate Asp.NET rather than WPF. Below are the details. Hope it gets you where you need to go!
After creating your server definition, here is the method in our WPF app that creates the server:
private void CreateServer()
{
string[] ipAddresses = GetLocalIPAddresses();
// insecure
m_server = new Server
{
Services =
{
GrpcServer.BindService(this).Intercept(new IpAddressAuthenticator())
}
};
// Add the IP addresses
for (int i = 0; i < ipAddresses.Length; i++)
{
m_server.Ports.Add(new ServerPort(ipAddresses[i], remPort, ServerCredentials.Insecure));
}
}
Here is the IpAddressAuthenticator code:
public class IpAddressAuthenticator : Interceptor
{
private readonly HashSet<string> m_authenticatedIps = new HashSet<string>()
{
"127.0.0.1",
"::1"
};
private void VerifyPeer(ServerCallContext context)
{
context.Status = new Status(StatusCode.OK, $"Authenticated peer: {context.Peer}");
}
private bool TryTakeIpAddress(string peer, out string ipAddress)
{
// ex.
// "ipv4:127.0.0.1:12345"
// "ipv6:[::1]:12345"
var ipv4Match = Regex.Match(peer, @"^ipv4:(.+):");
if (ipv4Match.Success)
{
ipAddress = ipv4Match.Groups[1].Value;
return true;
}
var ipv6Match = Regex.Match(peer, @"^ipv6:\[(.+)\]");
if (ipv6Match.Success)
{
ipAddress = ipv6Match.Groups[1].Value;
return true;
}
ipAddress = "";
return false;
}
public override Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod<TRequest, TResponse> continuation)
{
VerifyPeer(context);
return base.ClientStreamingServerHandler(requestStream, context, continuation);
}
public override Task DuplexStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, DuplexStreamingServerMethod<TRequest, TResponse> continuation)
{
VerifyPeer(context);
return base.DuplexStreamingServerHandler(requestStream, responseStream, context, continuation);
}
public override Task ServerStreamingServerHandler<TRequest, TResponse>(TRequest request, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, ServerStreamingServerMethod<TRequest, TResponse> continuation)
{
VerifyPeer(context);
return base.ServerStreamingServerHandler(request, responseStream, context, continuation);
}
public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
{
VerifyPeer(context);
return base.UnaryServerHandler(request, context, continuation);
}
}
Channel<T>
or similar as an intermediary – Bandylegged