Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
EddyHaigh opened this issue Feb 3, 2025 · 1 comment
Assignees
Labels
aspnet-core/svc grpc/subsvc Source - Docs.ms Docs Customer feedback via GitHub Issue

Comments

@EddyHaigh
Copy link

EddyHaigh commented Feb 3, 2025

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

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<GreeterService>();

app.Run();

Client

NamedPipesConnectionFactory.cs

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<Stream> 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

// 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

@wadepickett
Copy link
Contributor

@JamesNK, should the note under the Client configuration be expanded to help?

That section already states:
"Some connectivity features of GrpcChannel, such as client side load balancing and channel status, can't be used together with named pipes."

Maybe something like this that is more explicit?
"Some connectivity features of GrpcChannel, such as client-side load balancing and channel status, can't be used together with named pipes. If you need to use these features, do not configure a ConnectCallback for SocketsHttpHandler and use the default HTTP transport instead."

I am not entirely sure and could use your help on the guidance here, thanks.

@wadepickett wadepickett changed the title gRPC over Named Pipes sample broken gRPC over Named Pipes - Alternative option for client-side load balancing, channel status? Feb 3, 2025
@wadepickett wadepickett changed the title gRPC over Named Pipes - Alternative option for client-side load balancing, channel status? gRPC over Named Pipes - Alternative for client-side load balancing, channel status? Feb 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aspnet-core/svc grpc/subsvc Source - Docs.ms Docs Customer feedback via GitHub Issue
Projects
None yet
Development

No branches or pull requests

2 participants