将 gRPC 从 C-core 迁移到 gRPC for .NET
注意
此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 对于当前版本,请参阅此文的 .NET 8 版本。
由于基础堆栈的实现,不是所有功能在基于 C-core 的 gRPC 应用和 gRPC for .NET 之间都以相同的方式工作。 本文档重点介绍在两个堆栈之间迁移的主要区别。
重要
gRPC C-core 在维护模式下,并将被弃用而改为使用 gRPC for .NET。 对于新应用,不建议使用 gRPC C-core。
平台支持
gRPC C-core 和 gRPC for .NET 具有不同的平台支持:
- gRPC C-core:自带 TLS 和 HTTP/2 堆栈的 C++ gRPC 实现。
Grpc.Core
包是围绕 gRPC C-core 的 .NET 包装器,包含 gRPC 客户端和服务器。 它支持 .NET Framework、.NET Core 和 .NET 5 或更高版本。 - gRPC for .NET:专为 .NET Core 3.x 和 .NET 5 或更高版本设计。 它使用内置于新式 .NET 版本中的 TLS 和 HTTP/2 堆栈。
Grpc.AspNetCore
包包含托管在 ASP.NET Core 中的 gRPC 服务器,需要 .NET Core 3.x 或 .NET 5 或更高版本。Grpc.Net.Client
包包含一个 gRPC 客户端。Grpc.Net.Client
中的客户端对使用 WinHttpHandler 的 .NET Framework 的支持有限。
有关详细信息,请参阅 .NET 支持平台上的 gRPC。
配置服务器和通道
从 gRPC C-Core 迁移到 gRPC for .NET 时,必须修改 NuGet 包、配置和启动代码。
gRPC for .NET 为其客户端和服务器提供了单独的 NuGet 包。 添加的包取决于应用是托管 gRPC 服务还是调用它们:
Grpc.AspNetCore
:服务由 ASP.NET Core 托管。 有关服务器配置信息,请参阅使用 ASP.NET Core 的 gRPC 服务。Grpc.Net.Client
:客户端使用GrpcChannel
,它在内部使用内置于 .NET 的网络功能。 有关客户端配置信息,请参阅使用 .NET 客户端调用 gRPC 服务。
迁移完成后,应从应用中删除 Grpc.Core
包。 Grpc.Core
包含大型本机二进制文件,删除包可减少 NuGet 还原时间,并减小应用大小。
代码生成的服务和客户端
gRPC C-Core 和 gRPC for .NET 共享许多 API,从 .proto
文件生成的代码与这两种 gRPC 实现兼容。 大多数客户端和服务都可以从 C-Core 迁移到 gRPC for .NET,而不需要做任何改动。
gRPC 服务实现生存期
在 ASP.NET Core 堆栈中,默认情况下,创建的 gRPC 服务具有范围内的生存期。 与此相反,默认情况下,gRPC C-core 会绑定到具有单一实例生存期的服务。
范围内的生存期允许服务实现解析具有范围内的生存期的其他服务。 例如,范围内的生存期还可以通过构造函数注入解析 DI 容器中的 DbContext
。 使用范围内的生存期:
- 为每个请求构造服务实现的新实例。
- 不能通过实现类型上的实例成员在请求之间共享状态。
- 预期是在 DI 容器的单一实例服务中存储共享状态。 在 gRPC 服务实现的构造函数中解析存储的共享状态。
有关服务生存期的详细信息,请参阅 ASP.NET Core 中的依赖关系注入。
添加单一实例服务
为了促进从 gRPC C-core 实现到 ASP.NET Core 的转换,可以将服务实现的服务生存期从范围内改为单一实例。 这涉及到将服务实现的实例添加到 DI 容器:
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
services.AddSingleton(new GreeterService());
}
但是,具有单一实例生存期的服务实现不再能够通过构造函数注入来解析范围内的服务。
配置 gRPC 服务选项
在基于 C-core 的应用中,构造服务器实例时,使用 ChannelOption
配置 grpc.max_receive_message_length
和 grpc.max_send_message_length
等设置。
在 ASP.NET Core 中,gRPC 通过 GrpcServiceOptions
类型提供配置。 例如,可以通过 AddGrpc
配置 gRPC 服务的最大传入消息大小。 下面的示例将默认 MaxReceiveMessageSize
4 MB 更改为 16 MB:
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc(options =>
{
options.MaxReceiveMessageSize = 16 * 1024 * 1024; // 16 MB
});
}
有关配置的详细信息,请参阅 gRPC for .NET 配置。
Logging
基于 C-core 的应用依赖于 GrpcEnvironment
来配置记录器以进行调试。 ASP.NET Core 堆栈通过 Logging API 提供此功能。 例如,可以通过构造函数注入将记录器添加到 gRPC 服务:
public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}
有关 gRPC 日志记录和诊断的详细信息,请参阅 .NET 上的 gRPC 中的日志记录和诊断。
HTTPS
gRPC 侦听器
与基于 C-core 的 gRPC 应用中的拦截器相比,ASP.NET Core 中间件提供类似功能。 两者都受 ASP.NET Core gRPC 应用支持,因此无需重写侦听器。
有关这些功能比较情况的详细信息,请参阅 gRPC 侦听器与中间件。
非 ASP.NET Core 项目中的主机 gRPC
可将基于 C 核心的服务器添加到任何项目类型。 gRPC for .NET 服务器需要 ASP.NET Core。 ASP.NET Core 通常可用,因为项目文件将 Microsoft.NET.SDK.Web
指定为 SDK。
可以通过将 <FrameworkReference Include="Microsoft.AspNetCore.App" />
添加到项目来将 gRPC 服务器托管到非 ASP.NET Core 项目。 此框架参考使 ASP.NET Core API 可用,并且它们可用来启动 ASP.NET Core 服务器。
有关详细信息,请参阅将 gRPC 托管在非 ASP.NET Core 项目中。