IRemoteRequestHandler.InvokeAsync() never returns when using AddMessagePipeNamedPipeInterprocess
See original GitHub issueHi, I’m having a bit of trouble bringing up MessagePipe for IPC-RPC using named pipes. I’ve attempted to use the code described in the README, but to no avail.
I have create two projects, Client
and Server
using dotnet new worker
. Code is below. Server seems to run successfully, but never executes IAsyncRequestHandler.InvokeAsync
. Client never returns from the call to InvokeAsync
. Using MessagePipe 1.7.4, and .NET 6.0.
My apologies if I’m missing something obvious!
Client
Program.cs
using Client;
using MessagePipe;
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddMessagePipe();
services.AddMessagePipeNamedPipeInterprocess("sample-pipe", config => config.InstanceLifetime = InstanceLifetime.Singleton );
services.AddHostedService<Worker>();
})
.Build();
host.Run();
Worker.cs
using MessagePipe;
namespace Client;
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IRemoteRequestHandler<int, string> _remoteHandler;
public Worker(ILogger<Worker> logger, IRemoteRequestHandler<int, string> remoteHandler)
{
_logger = logger;
_remoteHandler = remoteHandler;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var result = await _remoteHandler.InvokeAsync(1234);
_logger.LogInformation("Received: {result}", result);
await Task.Delay(1000, stoppingToken);
}
}
}
Server
Program.cs
using MessagePipe;
using Server;
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<Worker>();
services.AddMessagePipe();
services.AddMessagePipeNamedPipeInterprocess("sample-pipe");
})
.Build();
host.Run();
public class MyAsyncHandler : IAsyncRequestHandler<int, string>
{
public async ValueTask<string> InvokeAsync(int request, CancellationToken cancellationToken = default)
{
await Task.Delay(1);
if (request == -1)
{
throw new Exception("NO -1");
}
else
{
return "ECHO:" + request.ToString();
}
}
}
Worker.cs is unmodified from the template.
Issue Analytics
- State:
- Created 7 months ago
- Comments:5
Top Results From Across the Web
No results found
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The problem seems to be that the NamedPipeWorker on the server side never gets initialized, thus not listens for connections. NamedPipeWorker will only be initialized by DI when a named pipe based request handler is created, but since no requests can be received, no request handler will get initialized. This is also the case with TCP based request handling.
Workaround for this problem is forcing initialization of NamedPipeWorker/TcpWorker by requesting an instance from the service provider. This way it will start listening for connections and requests can be received.
Also config.HostAsServer should be set to true for server side.
So server side code would then look like this:
It seems like you have not registered your MyAsyncHandler in the dependency injection container on the server-side. You need to register the handler in the ConfigureServices method of your server’s Program.cs like this:
services.AddSingleton<IAsyncRequestHandler<int, string>, MyAsyncHandler>();
Here’s the updated Program.cs for the server:
With these changes, your server should now execute the IAsyncRequestHandler.InvokeAsync method, and the client should receive the response.