Skip to content

Commit fa6682d

Browse files
authored
Add gRPC troubleshoot article (#13767)
1 parent 117e52f commit fa6682d

File tree

4 files changed

+120
-41
lines changed

4 files changed

+120
-41
lines changed

aspnetcore/grpc/aspnetcore.md

-39
Original file line numberDiff line numberDiff line change
@@ -82,45 +82,6 @@ The gRPC API provides access to some HTTP/2 message data, such as the method, ho
8282

8383
[!code-csharp[](~/grpc/aspnetcore/sample/GrcpService/GreeterService2.cs?highlight=6-7&name=snippet)]
8484

85-
## gRPC and ASP.NET Core on macOS
86-
87-
Kestrel doesn't support HTTP/2 with [Transport Layer Security (TLS)](https://tools.ietf.org/html/rfc5246) on macOS. The ASP.NET Core gRPC template and samples use TLS by default. You'll see the following error message when you attempt to start the gRPC server:
88-
89-
> Unable to bind to https://localhost:5001 on the IPv4 loopback interface: 'HTTP/2 over TLS is not supported on macOS due to missing ALPN support.'.
90-
91-
To work around this issue, configure Kestrel and the gRPC client to use HTTP/2 **without** TLS. You should only do this during development. Not using TLS will result in gRPC messages being sent without encryption.
92-
93-
Kestrel must configure a HTTP/2 endpoint without TLS in `Program.cs`:
94-
95-
```csharp
96-
public static IHostBuilder CreateHostBuilder(string[] args) =>
97-
Host.CreateDefaultBuilder(args)
98-
.ConfigureWebHostDefaults(webBuilder =>
99-
{
100-
webBuilder.ConfigureKestrel(options =>
101-
{
102-
// Setup a HTTP/2 endpoint without TLS.
103-
options.ListenLocalhost(5000, o => o.Protocols = HttpProtocols.Http2);
104-
});
105-
webBuilder.UseStartup<Startup>();
106-
});
107-
```
108-
109-
The gRPC client must set the `System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport` switch to `true` and use `http` in the server address:
110-
111-
```csharp
112-
// This switch must be set before creating the HttpClient.
113-
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
114-
115-
var httpClient = new HttpClient();
116-
// The port number(5000) must match the port of the gRPC server.
117-
httpClient.BaseAddress = new Uri("http://localhost:5000");
118-
var client = GrpcClient.Create<Greeter.GreeterClient>(httpClient);
119-
```
120-
121-
> [!WARNING]
122-
> HTTP/2 without TLS should only be used during app development. Production applications should always use transport security. For more information, see [Security considerations in gRPC for ASP.NET Core](xref:grpc/security#transport-security).
123-
12485
## Additional resources
12586

12687
* <xref:tutorials/grpc/grpc-start>

aspnetcore/grpc/troubleshoot.md

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
title: Troubleshoot gRPC on .NET Core
3+
author: jamesnk
4+
description: Troubleshoot errors when using gRPC on .NET Core.
5+
monikerRange: '>= aspnetcore-3.0'
6+
ms.author: jamesnk
7+
ms.custom: mvc
8+
ms.date: 08/12/2019
9+
uid: grpc/troubleshoot
10+
---
11+
# Troubleshoot gRPC on .NET Core
12+
13+
By [James Newton-King](https://twitter.com/jamesnk)
14+
15+
## Mismatch between client and service SSL/TLS configuration
16+
17+
The gRPC template and samples use [Transport Layer Security (TLS)](https://tools.ietf.org/html/rfc5246) to secure gRPC services by default. gRPC clients need to use a secure connection to call secured gRPC services successfully.
18+
19+
You can verify the ASP.NET Core gRPC service is using TLS in the logs written on app start. The service will be listening on an HTTPS endpoint:
20+
21+
```
22+
info: Microsoft.Hosting.Lifetime[0]
23+
Now listening on: https://localhost:5001
24+
info: Microsoft.Hosting.Lifetime[0]
25+
Application started. Press Ctrl+C to shut down.
26+
info: Microsoft.Hosting.Lifetime[0]
27+
Hosting environment: Development
28+
```
29+
30+
The .NET Core client must use `https` in the server address to make calls with a secured connection:
31+
32+
```csharp
33+
static async Task Main(string[] args)
34+
{
35+
var httpClient = new HttpClient();
36+
// The port number(5001) must match the port of the gRPC server.
37+
httpClient.BaseAddress = new Uri("https://localhost:5001");
38+
var client = GrpcClient.Create<Greeter.GreeterClient>(httpClient);
39+
}
40+
```
41+
42+
All gRPC client implementations support TLS. gRPC clients from other languages typically require the channel configured with `SslCredentials`. `SslCredentials` specifies the certificate that the client will use, and it must be used instead of insecure credentials. For examples of configuring the different gRPC client implementations to use TLS, see [gRPC Authentication](https://www.grpc.io/docs/guides/auth/).
43+
44+
## Call insecure gRPC services with .NET Core client
45+
46+
Additional configuration is required to call insecure gRPC services with the .NET Core client. The gRPC client must set the `System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport` switch to `true` and use `http` in the server address:
47+
48+
```csharp
49+
// This switch must be set before creating the HttpClient.
50+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
51+
52+
var httpClient = new HttpClient();
53+
// The port number(5000) must match the port of the gRPC server.
54+
httpClient.BaseAddress = new Uri("http://localhost:5000");
55+
var client = GrpcClient.Create<Greeter.GreeterClient>(httpClient);
56+
```
57+
58+
## Unable to start ASP.NET Core gRPC app on macOS
59+
60+
Kestrel doesn't support HTTP/2 with TLS on macOS and older Windows versions such as Windows 7. The ASP.NET Core gRPC template and samples use TLS by default. You'll see the following error message when you attempt to start the gRPC server:
61+
62+
> Unable to bind to https://localhost:5001 on the IPv4 loopback interface: 'HTTP/2 over TLS is not supported on macOS due to missing ALPN support.'.
63+
64+
To work around this issue, configure Kestrel and the gRPC client to use HTTP/2 *without* TLS. You should only do this during development. Not using TLS will result in gRPC messages being sent without encryption.
65+
66+
Kestrel must configure an HTTP/2 endpoint without TLS in *Program.cs*:
67+
68+
```csharp
69+
public static IHostBuilder CreateHostBuilder(string[] args) =>
70+
Host.CreateDefaultBuilder(args)
71+
.ConfigureWebHostDefaults(webBuilder =>
72+
{
73+
webBuilder.ConfigureKestrel(options =>
74+
{
75+
// Setup a HTTP/2 endpoint without TLS.
76+
options.ListenLocalhost(5000, o => o.Protocols = HttpProtocols.Http2);
77+
});
78+
webBuilder.UseStartup<Startup>();
79+
});
80+
```
81+
82+
The gRPC client must also be configured to not use TLS. For more information, see [Call insecure gRPC services with .NET Core client](#call-insecure-grpc-services-with-net-core-client).
83+
84+
> [!WARNING]
85+
> HTTP/2 without TLS should only be used during app development. Production apps should always use transport security. For more information, see [Security considerations in gRPC for ASP.NET Core](xref:grpc/security#transport-security).
86+
87+
## gRPC C# assets are not code generated from *\*.proto* files
88+
89+
gRPC code generation of concrete clients and service base classes requires protobuf files and tooling to be referenced from a project. You must include:
90+
91+
* *.proto* files you want to use in the `<Protobuf>` item group. [Imported *.proto* files](https://developers.google.com/protocol-buffers/docs/proto3#importing-definitions) must be referenced by the project.
92+
* Package reference to the gRPC tooling package [Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/).
93+
94+
For more information on generating gRPC C# assets, see <xref:grpc/basics>.
95+
96+
By default, a `<Protobuf>` reference generates a concrete client and a service base class. The reference element's `GrpcServices` attribute can be used to limit C# asset generation. Valid `GrpcServices` options are:
97+
98+
* `Both` (default when not present)
99+
* `Server`
100+
* `Client`
101+
* `None`
102+
103+
An ASP.NET Core web app hosting gRPC services only needs the service base class generated:
104+
105+
```xml
106+
<ItemGroup>
107+
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
108+
</ItemGroup>
109+
```
110+
111+
A gRPC client app making gRPC calls only needs the concrete client generated:
112+
113+
```xml
114+
<ItemGroup>
115+
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
116+
</ItemGroup>
117+
```

aspnetcore/toc.yml

+2
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,8 @@
547547
uid: grpc/migration
548548
- name: Comparing gRPC services with HTTP APIs
549549
uid: grpc/comparison
550+
- name: Troubleshoot
551+
uid: grpc/troubleshoot
550552
- name: Test, debug, and troubleshoot
551553
items:
552554
- name: Unit testing

aspnetcore/tutorials/grpc/grpc-start.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,12 @@ info: Microsoft.Hosting.Lifetime[0]
115115
Application started. Press Ctrl+C to shut down.
116116
info: Microsoft.Hosting.Lifetime[0]
117117
Hosting environment: Development
118-
info: Microsoft.Hosting.Lifetime[0]
119118
```
120119

121120
> [!NOTE]
122121
> The gRPC template is configured to use [Transport Layer Security (TLS)](https://tools.ietf.org/html/rfc5246). gRPC clients need to use HTTPS to call the server.
123122
>
124-
> macOS doesn't support ASP.NET Core gRPC with TLS. Additional configuration is required to successfully run gRPC services on macOS. For more information, see [gRPC and ASP.NET Core on macOS](xref:grpc/aspnetcore#grpc-and-aspnet-core-on-macos).
123+
> macOS doesn't support ASP.NET Core gRPC with TLS. Additional configuration is required to successfully run gRPC services on macOS. For more information, see [Unable to start ASP.NET Core gRPC app on macOS](xref:grpc/troubleshoot#unable-to-start-aspnet-core-grpc-app-on-macos).
125124
126125
### Examine the project files
127126

0 commit comments

Comments
 (0)