I've started playing with gRPC
, having 3 projects:
This is what I see often:
Status(StatusCode="Unavailable", Detail="Error starting gRPC call. HttpRequestException: No connection could be made because the target machine actively refused it. (localhost:80) SocketException: No connection could be made because the target machine actively refused it.", DebugException="System.Net.Http.HttpRequestException: No connection could be made because the target machine actively refused it. (localhost:80)")
This error is welcoming me more often during the debugging.
I'm using Unix Domain Sockets
as a communication protocol.
My Program.cs
is configured in that way:
var builder = WebApplication.CreateBuilder(args);
var socketPath = Path.Combine(@"C:\Temp", "app-socket.socket");
builder.Services.AddSingleton<Settings>();
builder.Services.AddGrpc();
builder.Services.AddSingleton<ISettingsService>(provider => provider.GetRequiredService<Settings>());
builder.Services.AddSingleton<IConnectionService>(provider =>
{
var settings = provider.GetRequiredService<Settings>();
return new ConnectionService(settings.GetAServerAddress(), Settings.GetBServerAddress());
});
builder.Services.AddSingleton<IPackageService>(provider => { return new PackageService(provider.GetRequiredService<Settings>()); });
builder.WebHost.ConfigureKestrel(serverOptions =>
{
if (File.Exists(socketPath))
{
File.Delete(socketPath);
}
serverOptions.ListenUnixSocket(socketPath, listenOptions =>
{
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
});
});
builder.Host.UseWindowsService();
builder.Services.AddGrpcReflection();
var app = builder.Build();
app.MapGrpcService<GrpcSettingsService>();
app.MapGrpcService<GrpcConnectionService>();
app.MapGrpcService<GrpcPackageService>();
app.MapGrpcReflectionService();
Console.WriteLine($"gRPCServer is running and listening on {socketPath}");
app.Run();
On the Client I have something like:
public partial class MainWindow : Window
{
private readonly GrpcChannel _channel;
private readonly GrpcSettings.GrpcSettingsClient _grpcSettingsClient;
public MainWindow()
{
Task.Delay(5000);
InitializeComponent();
var socketPath = Path.Combine(@"C:\Temp", "app-socket.socket");
_channel = GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
{
HttpHandler = CreateHttpHandler(socketPath)
});
_grpcSettingsClient = new GrpcSettings.GrpcSettingsClient(_channel);
DataContext = new MainViewModel(_grpcSettingsClient);
}
private static HttpMessageHandler CreateHttpHandler(string socketPath)
{
var udsEndPoint = new UnixDomainSocketEndPoint(socketPath);
return new SocketsHttpHandler
{
ConnectCallback = async (context, cancellationToken) =>
{
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
await socket.ConnectAsync(udsEndPoint, cancellationToken);
return new NetworkStream(socket, ownsSocket: true);
}
};
}
}
The Task.Delay(5000)
was added to be sure that the Server will start before GUI, when I combined "Multiple Statup Options".
I was trying multiple things, but when I play with it more and more it starts to occurs more often.
I'm wondering what is happening, because I'm not using any ports, but all things are done through socket...
In the production GRPC Server will run as a Windows Service as different User & GUI will be run as a local one.
For debug case I forgot to await
the Task
of delay.
public MainWindow()
{
Task.Delay(2000).Wait();
InitializeComponent();
// rest of the code
}
So the solution was simple and stupid :)