I have 3 Projects: ClientA, ServerA, ServerB.
Client A is a client to the server ServerA, ServerA is both Server for ClientA and a client towards ServerB. They all share a .Net Framework Class Library, which contains the .proto file and the generated Clients / ServerImpls. The .proto file gets atomatically interpreted using:
<ItemGroup>
<Protobuf Include="protos\proto.proto" OutputDir="%(RelativePath)" CompileOutputs="false" />
</ItemGroup>
ServerA can call methods from ServerB, but ClientA can not call methods from ServerA (see error in title).
The .proto file looks like this:
message Ping{
int64 timestamp = 1;
}
message Pong {
int64 timestamp = 1;
}
service ServerAService {
rpc TestConnection(Ping) returns (Pong);
}
service ServerBService {
rpc TestConnection(Ping) returns (Pong);
}
Client A is a .NET Framework 4.7.2 Excel Add-in with these packages:

It Connects to ServerA with this code:
Channel channel = new Channel("127.0.0.1:" + 50051, ChannelCredentials.Insecure);
client = new ServerAService.ServerAServiceClient(channel);
if (client.TestConnection(new Ping { Timestamp = DateTime.Now.Ticks }, null) != null)
{ [...]
ServerA is a ASP.NET Core 3.1 Application with the ServerImpl started via Dependency Injection:
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<ServerAServiceImpl>();
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
and, since IIS does not support gRPC, using Kestrel configured like this:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<StartupServerA>();
webBuilder.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 50051, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
});
ServerA also has theese packages:
ServerA does the same as ClientA does to connect:
var channel = new Channel("localhost:50033", ChannelCredentials.Insecure);
ServerBClient serverb = new ServerBClient(channel);
if (serverb.TestConnection(new Ping(), null) != null)
{ [...]
ServerB is also an ASP.NET Core 3.1 App:
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<ServerBServiceImpl>();
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("ServerB Running!");
});
});
With kestrel, too:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.AddConsole();
}
).ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<StartupServerB>();
webBuilder.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 50033, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
});
and theese packages:
When ClientA calls the ServerA.TestConnection procedure, the error "Received http2 header with status 307" occurs. ServerA can call the ServerB.TestConnection without a problem.
Before switching to ASP.NET Core 3.1 the ServerA and ServerB were running as .NET Framework Console Applications, and were just changed during a refactoring. When everything was running on .NET Framework, ClientA was able to ServerA.TestConnection successfully. Are grpc on .netframework and .netcore incompatible?
What does "Received http2 header with status 307" even mean? I hope someone has a clue.
Edit: As suggested by Marc i created a blank project to ultimately upload the test case to github, and could figure out from that that the implementation of "Blazor" is blocking gRPC here. So its not a .net FRAMEWORK <> Core compatiblity issue, its a Blazor <> gRPC issue. I will try to narrow down why blazor redirects the gRPC call, even though its on another port. Maybe gRPC and Blazor need to be run in different services after all.

