I have a simple asp.net website that communicates over gRPC to a backend windows service. The web part is published on Azure App Service (gRPC client) and the gRPC Server is installed on an Azure VM.
My gRPC Server was built with Topshelf in order to accomplish the Windows Service requirement. Here is my server code
public class MyServer
{
private Server _server;
public void Start()
{
try
{
var port = Convert.ToInt32(ConfigurationManager.AppSettings["GrpcPort"]);
var host = ConfigurationManager.AppSettings["GrpcHost"];
_server = new Server(new []
{
new ChannelOption(ChannelOptions.MaxSendMessageLength, 256 * 1024 * 1024),
new ChannelOption(ChannelOptions.MaxReceiveMessageLength, 256 * 1024 * 1024),
})
{
Services =
{
GrpcServices.Datalog.DatalogService.BindService(
new DatalogGrpcService()
)
},
Ports =
{
new ServerPort(host, port, ServerCredentials.Insecure)
}
};
_server.Start();
Logger.Instance.Debug("DatalogServer",
$"Datalog Grpc Server is listening on port {port}");
}
catch (Exception e)
{
Logger.Instance.Error("DatalogServer", e);
}
}
public void Stop()
{
_server?.KillAsync().Wait();
}
}
The gRPC Service is configured like that
<add key="GrpcPort" value="8005"/>
<add key="GrpcHost" value="0.0.0.0"/>
On the ASP.Net part, here is how I consume the gRPC Service
public class DatalogService : IDisposable
{
private readonly Channel _grpcChannel;
private readonly GrpcServices.Datalog.DatalogService.DatalogServiceClient _grpcClient;
public DatalogService(string grpcHost, string grpcPort)
{
try
{
_grpcChannel = new Channel(
$"{grpcHost}:{grpcPort}",
ChannelCredentials.Insecure, new []
{
new ChannelOption(ChannelOptions.MaxSendMessageLength, 256 * 1024 * 1024),
new ChannelOption(ChannelOptions.MaxReceiveMessageLength, 256 * 1024 * 1024),
});
_grpcClient = new GrpcServices.Datalog.DatalogService.DatalogServiceClient(_grpcChannel);
Logger.Instance.Error(string.Empty, $"client started on {grpcHost}:{grpcPort}");
}
catch (Exception e)
{
Logger.Instance.Error(string.Empty, "DatlogService Ctor", e);
}
}
public async Task<bool> IsAlive(int installationId)
{
try
{
var result = await _grpcClient.IsAliveAsync(new HasEnhancedDbRequest
{
InstallationId = installationId
});
return result.IsAlive;
}
catch (Exception e)
{
Logger.Instance.Error(string.Empty, e);
return false;
}
}
public void Dispose()
{
_grpcChannel?.ShutdownAsync().Wait();
}
From Azure App Service, I ask my gRPC Server with the address "my-vm-machine-name.privatelink.database.windows.net". This is the address that Azure Support gave me. We must use this because of a virtual network configuration.
When I try my implementation on different PC on my network, everything is fine. When I try this implementation on the Azure part, I get this error
Status(StatusCode="Unavailable",
Detail="failed to connect to all addresses",
DebugException="Grpc.Core.Internal.CoreErrorDetailException:
{
"created":"@1597047075.686000000",
"description":"Failed to pick subchannel", "file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\client_channel.cc",
"file_line":3948,"referenced_errors":[{"created":"@1597047075.686000000","description":"failed to connect to all addresses","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\lb_policy\pick_first\pick_first.cc","file_line":394,"grpc_status":14}]
}")
I am turning around to find a solution. I am pretty sure that my code works well because, as I said before, on my local network everything is fine.
From the Azure App Service, when I try to tcpping on port 8005, it says it's open.
Anyone has experienced such an issue?
Thank you for your help !