dotnet / dotnet/AspNetCore.Docs

gRPC over Named Pipes - Alternative for client-side load balancing, channel status?

Open
#34,620 2 comments 0 reactions 1 assignee Claimed by @wadepickett View on GitHub
aspnet-core/svc grpc/subsvc Source - Docs.ms
Dominant language
C#
Stars
13.1k
Forks
24.6k
Avg merge
1d 3h
Merged PRs (30d)
97

Description

### Description

# Problem

When creating a basic gRPC over Named Pipes application from the code of the documentation, the code breaks with the following error code on the `channel.ConnectAsync();`.

Even though there is a note about regarding the things mentioned it doesn't explain anything about how to disable.

```
System.InvalidOperationException: 'Channel is configured with an HTTP transport doesn't support client-side load balancing or connectivity state tracking. The underlying HTTP transport must be a SocketsHttpHandler with no SocketsHttpHandler.ConnectCallback configured. The HTTP transport must be configured on the channel using GrpcChannelOptions.HttpHandler.'
```

## Code

### Server

#### Program.cs

```csharp
using GrpcService1.Services;

using Microsoft.AspNetCore.Server.Kestrel.Core;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddGrpc();

builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenNamedPipe("MyPipeName", listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});

var app = builder.Build();

// Configure the HTTP request pipeline.
app.MapGrpcService();

app.Run();
```

### Client

#### NamedPipesConnectionFactory.cs

```csharp
using Grpc.Net.Client;

using System.IO.Pipes;
using System.Security.Principal;

public class NamedPipesConnectionFactory
{
private readonly string pipeName;

public NamedPipesConnectionFactory(string pipeName)
{
this.pipeName = pipeName;
}

public async ValueTask ConnectAsync(SocketsHttpConnectionContext _,
CancellationToken cancellationToken = default)
{
var clientStream = new NamedPipeClientStream(
serverName: ".",
pipeName: this.pipeName,
direction: PipeDirection.InOut,
options: PipeOptions.WriteThrough | PipeOptions.Asynchronous,
impersonationLevel: TokenImpersonationLevel.Anonymous);

try
{
await clientStream.ConnectAsync(cancellationToken).ConfigureAwait(false);
return clientStream;
}
catch
{
clientStream.Dispose();
throw;
}
}

public static GrpcChannel CreateChannel()
{
var connectionFactory = new NamedPipesConnectionFactory("MyPipeName");
var socketsHttpHandler = new SocketsHttpHandler
{
ConnectCallback = connectionFactory.ConnectAsync
};

return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
{
HttpHandler = socketsHttpHandler,
});
}
}
```

#### Program.cs

```csharp
// See https://aka.ms/new-console-template for more information
using GrpcService1;

var channel = NamedPipesConnectionFactory.CreateChannel();

await channel.ConnectAsync();

var greeter = new Greeter.GreeterClient(channel);

do
{
await greeter.SayHelloAsync(new HelloRequest { Name = "World" });

} while (true);
```

### Page URL

https://learn.microsoft.com/en-us/aspnet/core/grpc/interprocess-namedpipes?view=aspnetcore-9.0

### Content source URL

https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/grpc/interprocess-namedpipes.md

### Document ID

58d486b8-0e04-9767-2089-deb43a28f56b

### Article author

@JamesNK

### Metadata

* ID: 58d486b8-0e04-9767-2089-deb43a28f56b
* Service: **aspnet-core**
* Sub-service: **grpc**

[Related Issues](https://github.com/dotnet/AspNetCore.Docs/issues?q=is%3Aissue+is%3Aopen+58d486b8-0e04-9767-2089-deb43a28f56b)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.