教程:在 ASP.NET Core 中创建 gRPC 客户端和服务器
作者:John Luo
本教程演示了如何创建 .NET Core gRPC 客户端和 ASP.NET Core gRPC 服务器。
最后会生成与 gRPC Greeter 服务进行通信的 gRPC 客户端。
在本教程中,你将了解:
- 创建 gRPC 服务器。
- 创建 gRPC 客户端。
- 使用 gRPC Greeter 服务测试 gRPC 客户端服务。
系统必备
-
Visual Studio
- Visual Studio 2019 与 ASP.NET 和 Web 开发 工作负载
-
Visual Studio Code
Visual Studio Code 说明使用用于 ASP.NET Core 的 .NET Core CLI 开发功能,如项目创建。 可在任何平台(macOS、Linux 或 Windows)上或在任何代码编辑器中遵循这些说明。 如果使用 Visual Studio Code 以外的其他内容,则可能需要进行少量更改。
- Visual Studio for Mac
创建 gRPC 服务
-
Visual Studio
启动 Visual Studio 并选择“创建新项目”。 或者,从 Visual Studio“文件”菜单中选择“新建” > “项目”。
在“创建新项目”对话框中,选择“gRPC 服务”,然后选择“下一步”:
将项目命名为 GrpcGreeter。 将项目命名为“GrpcGreeter”非常重要,这样在复制和粘贴代码时命名空间就会匹配。
选择“创建”。
在“创建新 gRPC 服务”对话框中:
- 选择“gRPC 服务”模板。
- 选择“创建”。
-
Visual Studio Code
打开集成终端。
将目录更改为 (
cd
) 包含项目的文件夹。运行以下命令:
dotnet new grpc -o GrpcGreeter code -r GrpcGreeter
dotnet new
命令将在 GrpcGreeter 文件夹中创建一个新 gRPC 服务。code
命令将在新 Visual Studio Code 实例中打开 GrpcGreeter 文件夹。
一个对话框随即出现,其中包含:“‘GrpcGreeter’中缺少进行生成和调试所需的资产”。是否添加它们?”
选择 “是”。
-
Visual Studio for Mac
从终端运行以下命令:
dotnet new grpc -o GrpcGreeter cd GrpcGreeter
上述命令使用 .NET Core CLI 创建 gRPC 服务。
打开项目
在 Visual Studio 中,选择“文件” > “打开”,然后选择“GrpcGreeter.csproj”文件。
运行服务
-
Visual Studio
按 Ctrl+F5 以在不使用调试程序的情况下运行。
Visual Studio 会显示以下对话框:
如果信任 IIS Express SSL 证书,请选择“是” 。
将显示以下对话框:
如果你同意信任开发证书,请选择“是”。
Visual Studio 启动 IIS Express 并运行应用。 地址栏显示
localhost:port#
,而不是显示example.com
。 这是因为localhost
是本地计算机的标准主机名。 Localhost 仅为来自本地计算机的 Web 请求提供服务。 Visual Studio 创建 Web 项目时,Web 服务器使用的是随机端口。
-
Visual Studio Code
通过运行以下命令来信任 HTTPS 开发证书:
dotnet dev-certs https --trust
上述命令在 Linux 上无效。 有关信任证书的详细信息,请参阅 Linux 发行版的文档。
以上命令会显示以下对话:
如果你同意信任开发证书,请选择“是”。
有关详细信息,请参阅信任 ASP.NET Core HTTPS 开发证书。
按 Ctrl-F5 以在不使用调试程序的情况下运行。
Visual Studio Code 启动 Kestrel,启动浏览器并导航到
http://localhost:5001
。 地址栏显示localhost:port#
,而不是显示example.com
。 这是因为localhost
是本地计算机的标准主机名。 Localhost 仅为来自本地计算机的 Web 请求提供服务。
-
Visual Studio for Mac
Visual Studio for Mac 会显示以下弹出窗口:
如果你信任开发证书,请选择“是”。
将显示以下对话框:
输入你的密码,然后选择“确定”
如果你同意信任开发证书,请选择“是”。
有关详细信息,请参阅信任 ASP.NET Core HTTPS 开发证书
在 Visual Studio 中,按“Opt-Cmd-Return”可在不使用调试器的情况下运行 。 或者,导航到菜单栏,转到“运行”>“在不调试的情况下启动” 。
Visual Studio 启动 Kestrel,启动浏览器并导航到
http://localhost:5001
。
日志显示该服务正在侦听 https://localhost:5001
。
info: Microsoft.Hosting.Lifetime[0] Now listening on: https://localhost:5001 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development
备注
gRPC 模板配置为使用传输层安全性 (TLS)。 gRPC 客户端需要使用 HTTPS 调用服务器。
macOS 不支持 ASP.NET Core gRPC 及 TLS。 在 macOS 上成功运行 gRPC 服务需要其他配置。 有关详细信息,请参阅无法在 macOS 上启用 ASP.NET Core gRPC 应用。
检查项目文件
GrpcGreeter 项目文件:
- greet.proto – Protos/greet.proto 文件定义
Greeter
gRPC,且用于生成 gRPC 服务器资产。 有关详细信息,请参阅 gRPC 介绍。 - Services 文件夹:包含
Greeter
服务的实现。 - appSettings.json – 包含配置数据,如 Kestrel 使用的协议。 有关详细信息,请参阅 ASP.NET Core 中的配置。
- Program.cs – 包含 gRPC 服务的入口点。 有关详细信息,请参阅 .NET 通用主机。
- Startup.cs – 包含配置应用行为的代码。 有关详细信息,请参阅应用启动。
在 .NET 控制台应用中创建 gRPC 客户端
-
Visual Studio
- 打开 Visual Studio 的第二个实例并选择“创建新项目”。
- 在“创建新项目”对话框中,选择“控制台应用(.NET Core)”,然后选择“下一步”。
- 在“名称”文本框中,输入“GrpcGreeterClient”,然后选择“创建”。
-
Visual Studio Code
打开集成终端。
将目录更改为 (
cd
) 包含项目的文件夹。运行以下命令:
dotnet new console -o GrpcGreeterClient code -r GrpcGreeterClient
-
Visual Studio for Mac
按照使用 Visual Studio for Mac 在 macOS 上构建完整的 .NET Core 解决方案中的说明创建名为 GrpcGreeterClient 的控制台应用。
添加所需的包
gRPC 客户端项目需要以下包:
- Grpc.Net.Client,其中包含 .NET Core 客户端。
- Google.Protobuf 包含适用于 C# 的 Protobuf 消息。
- Grpc.Tools 包含适用于 Protobuf 文件的 C# 工具支持。 运行时不需要工具包,因此依赖项标记为
PrivateAssets="All"
。
-
Visual Studio
通过包管理器控制台 (PMC) 或管理 NuGet 包来安装包。
用于安装包的 PMC 选项
从 Visual Studio 中,依次选择“工具” > “NuGet 包管理器” > “包管理器控制台”
从“包管理器控制台”窗口中,运行
cd GrpcGreeterClient
以将目录更改为包含 GrpcGreeterClient.csproj 文件的文件夹。运行以下命令:
Install-Package Grpc.Net.Client Install-Package Google.Protobuf Install-Package Grpc.Tools
管理 NuGet 包选项以安装包
- 右键单击“解决方案资源管理器” > “管理 NuGet 包”中的项目
- 选择“浏览”选项卡。
- 在搜索框中输入 Grpc.Net.Client。
- 从“浏览”选项卡中选择“Grpc.Net.Client”包,然后选择“安装”。
- 为
Google.Protobuf
和Grpc.Tools
重复这些步骤。
-
Visual Studio Code
从“集成终端”运行以下命令:
dotnet add GrpcGreeterClient.csproj package Grpc.Net.Client dotnet add GrpcGreeterClient.csproj package Google.Protobuf dotnet add GrpcGreeterClient.csproj package Grpc.Tools
-
Visual Studio for Mac
- 右键单击“Solution Pad” > “添加包...”中的“包”文件夹
- 在搜索框中输入 Grpc.Net.Client。
- 从结果窗格中选择 Grpc.Net.Client 包并选择“添加包”
- 为
Google.Protobuf
和Grpc.Tools
重复这些步骤。
添加 greet.proto
在 gRPC 客户端项目中创建 Protos 文件夹。
从 gRPC Greeter 服务将 Protos\greet.proto 文件复制到 gRPC 客户端项目。
编辑 GrpcGreeterClient.csproj 项目文件:
-
Visual Studio
右键单击项目,并选择“编辑项目文件”。
-
Visual Studio Code
选择 GrpcGreeterClient.csproj 文件。
-
Visual Studio for Mac
右键单击项目,并选择“工具” > “编辑文件”。
-
Visual Studio
添加具有引用 greet.proto 文件的
<Protobuf>
元素的项组:<ItemGroup> <Protobuf Include="Protos\greet.proto" GrpcServices="Client" /> </ItemGroup>
创建 Greeter 客户端
构建项目,以在 GrpcGreeter
命名空间中创建类型。 GrpcGreeter
类型是由生成进程自动生成的。
使用以下代码更新 gRPC 客户端的 Program.cs 文件:
using System; using System.Net.Http; using System.Threading.Tasks; using GrpcGreeter; using Grpc.Net.Client; namespace GrpcGreeterClient { class Program { static async Task Main(string[] args) { // The port number(5001) must match the port of the gRPC server. using var channel = GrpcChannel.ForAddress("https://localhost:5001"); var client = new Greeter.GreeterClient(channel); var reply = await client.SayHelloAsync( new HelloRequest { Name = "GreeterClient" }); Console.WriteLine("Greeting: " + reply.Message); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } } }
Program.cs 包含 gRPC 客户端的入口点和逻辑。
通过以下方式创建 Greeter 客户端:
- 实例化
GrpcChannel
,使其包含用于创建到 gRPC 服务的连接的信息。 - 使用
GrpcChannel
构造 Greeter 客户端:
static async Task Main(string[] args) { // The port number(5001) must match the port of the gRPC server. using var channel = GrpcChannel.ForAddress("https://localhost:5001"); var client = new Greeter.GreeterClient(channel); var reply = await client.SayHelloAsync( new HelloRequest { Name = "GreeterClient" }); Console.WriteLine("Greeting: " + reply.Message); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); }
Greeter 客户端会调用异步 SayHello
方法。 随即显示 SayHello
调用的结果:
static async Task Main(string[] args) { // The port number(5001) must match the port of the gRPC server. using var channel = GrpcChannel.ForAddress("https://localhost:5001"); var client = new Greeter.GreeterClient(channel); var reply = await client.SayHelloAsync( new HelloRequest { Name = "GreeterClient" }); Console.WriteLine("Greeting: " + reply.Message); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); }
使用 gRPC Greeter 服务测试 gRPC 客户端
-
Visual Studio
- 在 Greeter 服务中,按
Ctrl+F5
在不使用调试程序的情况下启动服务器。 - 在
GrpcGreeterClient
项目中,按Ctrl+F5
在不使用调试程序的情况下启动客户端。
- 在 Greeter 服务中,按
-
Visual Studio Code
- 启动 Greeter 服务。
- 启动客户端。
-
Visual Studio for Mac
- 启动 Greeter 服务。
- 启动客户端。
客户端向该服务发送一条包含具有其名称“GreeterClient”的消息的问候信息。 该服务会发送“Hello GreeterClient”消息作为答复。 “Hello GreeterClient”答复将在命令提示符中显示:
Greeting: Hello GreeterClient Press any key to exit...
gRPC 服务在写入命令提示符的日志中记录成功调用的详细信息:
info: Microsoft.Hosting.Lifetime[0] Now listening on: https://localhost:5001 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: C:\GH\aspnet\docs\4\Docs\aspnetcore\tutorials\grpc\grpc-start\sample\GrpcGreeter info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/2 POST https://localhost:5001/Greet.Greeter/SayHello application/grpc info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0] Executing endpoint 'gRPC - /Greet.Greeter/SayHello' info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1] Executed endpoint 'gRPC - /Greet.Greeter/SayHello' info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 78.32260000000001ms 200 application/grpc
备注
本文中的代码需要 ASP.NET Core HTTPS 开发证书来保护 gRPC 服务。 如果客户端失败并显示消息 The remote certificate is invalid according to the validation procedure.
,则开发证书不受信任。 有关解决此问题的说明,请参阅在 Windows 和 macOS 上信任 ASP.NET Core HTTPS 开发证书。
Azure 应用服务不支持 gRPC
警告
Azure 应用服务或 IIS 当前不支持 ASP.NET Core gRPC。 Http.Sys 的 HTTP/2 实现不支持 gRPC 依赖的 HTTP 响应尾随标头。 有关详细信息,请参阅此 GitHub 问题。
后续步骤
下一篇:gRPC 服务与 C#