使用 ASP.NET Core 的 gRPC 服务gRPC services with ASP.NET Core

本文档演示如何通过 ASP.NET Core 开始使用 gRPC 服务。This document shows how to get started with gRPC services using ASP.NET Core.

警告

若要将 ASP.NET Core gRPC 用于 Azure 应用服务或 IIS,则该 gRPC 具有额外的要求。ASP.NET Core gRPC has extra requirements for being used with Azure App Service or IIS. 有关 gRPC 可用于何处的详细信息,请参阅 .NET 上的 gRPC 支持的平台For more information on where gRPC can be used, see .NET 上的 gRPC 支持的平台.

先决条件Prerequisites

开始使用 ASP.NET Core 中的 gRPC 服务Get started with gRPC service in ASP.NET Core

查看或下载示例代码如何下载)。View or download sample code (how to download).

请参阅 gRPC 服务入门,获取关于如何创建 gRPC 项目的详细说明。See Get started with gRPC services for detailed instructions on how to create a gRPC project.

将 gRPC 服务添加到 ASP.NET Core 应用Add gRPC services to an ASP.NET Core app

gRPC 需要 Grpc.AspNetCore 包。gRPC requires the Grpc.AspNetCore package.

配置 gRPCConfigure gRPC

在 Startup.cs 中:In Startup.cs:

  • gRPC 通过 AddGrpc 方法启用。gRPC is enabled with the AddGrpc method.
  • 每个 gRPC 服务均通过 MapGrpcService 方法添加到路由管道。Each gRPC service is added to the routing pipeline through the MapGrpcService method.
public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            // Communication with gRPC endpoints must be made through a gRPC client.
            // To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909
            endpoints.MapGrpcService<GreeterService>();
        });
    }
}

若要查看翻译为非英语语言的代码注释,请在 此 GitHub 讨论问题中告诉我们。If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.

ASP.NET Core 中间件和功能共享路由管道,因此可以将应用配置为提供其他请求处理程序。ASP.NET Core middleware and features share the routing pipeline, therefore an app can be configured to serve additional request handlers. 其他请求处理程序(如 MVC 控制器)与已配置的 gRPC 服务并行工作。The additional request handlers, such as MVC controllers, work in parallel with the configured gRPC services.

服务器选项Server options

gRPC 服务可由所有内置 ASP.NET Core 服务器托管。gRPC services can be hosted by all built-in ASP.NET Core servers.

  • Kestrel
  • TestServerTestServer
  • IIS†IIS†
  • HTTP.sys‡HTTP.sys‡

†IIS 需要 .NET 5 和 Windows 10 内部版本 20300.1000 或更高版本。†IIS requires .NET 5 and Windows 10 Build 20300.1000 or later.
‡HTTP.sys 需要 .NET 5 和 Windows 10 内部版本 19529 或更高版本。‡HTTP.sys requires .NET 5 and Windows 10 Build 19529 or later.

上述 Windows 10 内部版本可能需要使用 Windows 预览体验成员内部版本。The preceding Windows 10 Build versions may require the use of a Windows Insider build.

有关为 ASP.NET Core 应用选择正确的服务器的详细信息,请参阅 ASP.NET Core 中的 Web 服务器实现For more information about choosing the right server for an ASP.NET Core app, see ASP.NET Core 中的 Web 服务器实现.

Kestrel

Kestrel 是一个跨平台的适用于 ASP.NET Core 的 Web 服务器。Kestrel is a cross-platform web server for ASP.NET Core. Kestrel 提供了最佳性能和内存利用率,但它没有 HTTP.sys 中的某些高级功能,如端口共享。Kestrel provides the best performance and memory utilization, but it doesn't have some of the advanced features in HTTP.sys such as port sharing.

Kestrel gRPC 终结点:Kestrel gRPC endpoints:

HTTP/2HTTP/2

gRPC 需要 HTTP/2。gRPC requires HTTP/2. 适用于 ASP.NET Core 的 gRPC 验证 HttpRequest.ProtocolHTTP/2gRPC for ASP.NET Core validates HttpRequest.Protocol is HTTP/2.

Kestrel 在大多数新式操作系统上支持 HTTP/2Kestrel supports HTTP/2 on most modern operating systems. 默认情况下,Kestrel 终结点配置为支持 HTTP/1.1 和 HTTP/2 连接。Kestrel endpoints are configured to support HTTP/1.1 and HTTP/2 connections by default.

TLSTLS

用于 gRPC 的 Kestrel 终结点应使用 TLS 进行保护。Kestrel endpoints used for gRPC should be secured with TLS. 在开发环境中,当存在 ASP.NET Core 开发证书时,会在 https://localhost:5001 自动创建使用 TLS 进行保护的终结点。In development, an endpoint secured with TLS is automatically created at https://localhost:5001 when the ASP.NET Core development certificate is present. 不需要任何配置。No configuration is required. https 前缀验证 Kestrel 终结点是否正在使用 TLS。An https prefix verifies the Kestrel endpoint is using TLS.

在生产环境中,必须显式配置 TLS。In production, TLS must be explicitly configured. 以下 appsettings.json 示例中提供了使用 TLS 进行保护的 HTTP/2 终结点:In the following appsettings.json example, an HTTP/2 endpoint secured with TLS is provided:

{
  "Kestrel": {
    "Endpoints": {
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Protocols": "Http2",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      }
    }
  }
}

或者,可以在 Program.cs 中配置 Kestrel 终结点:Alternatively, Kestrel endpoints can be configured in Program.cs:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(options =>
            {
                options.Listen(IPAddress.Any, 5001, listenOptions =>
                {
                    listenOptions.Protocols = HttpProtocols.Http2;
                    listenOptions.UseHttps("<path to .pfx file>", 
                        "<certificate password>");
                });
            });
            webBuilder.UseStartup<Startup>();
        });

协议协商Protocol negotiation

TLS 的用途不仅限于保护通信。TLS is used for more than securing communication. 当终结点支持多个协议时,TLS 应用程序层协议协商 (ALPN) 握手可用于协商客户端与服务器之间的连接协议。The TLS Application-Layer Protocol Negotiation (ALPN) handshake is used to negotiate the connection protocol between the client and the server when an endpoint supports multiple protocols. 此协商确定连接是使用 HTTP/1.1 还是 HTTP/2。This negotiation determines whether the connection uses HTTP/1.1 or HTTP/2.

如果在不使用 TLS 的情况下配置了 HTTP/2 终结点,则必须将终结点的 ListenOptions.Protocols 设置为 HttpProtocols.Http2If an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2. 如果没有 TLS,则无法使用具有多个协议(例如 HttpProtocols.Http1AndHttp2)的终结点,因为没有协商。An endpoint with multiple protocols (for example, HttpProtocols.Http1AndHttp2) can't be used without TLS because there's no negotiation. 到不安全终结点的所有连接均默认为 HTTP/1.1,且 gRPC 调用会失败。All connections to the unsecured endpoint default to HTTP/1.1, and gRPC calls fail.

有关使用 Kestrel 启用 HTTP/2 和 TLS 的详细信息,请参阅 Kestrel 终结点配置For more information on enabling HTTP/2 and TLS with Kestrel, see Kestrel endpoint configuration.

备注

macOS 不支持 ASP.NET Core gRPC 及 TLS。macOS doesn't support ASP.NET Core gRPC with TLS. 在 macOS 上成功运行 gRPC 服务需要其他配置。Additional configuration is required to successfully run gRPC services on macOS. 有关详细信息,请参阅无法在 macOS 上启用 ASP.NET Core gRPC 应用For more information, see Unable to start ASP.NET Core gRPC app on macOS.

IISIIS

Internet Information Services (IIS) 是一种灵活、安全且可管理的 Web 服务器,用于托管 Web 应用(包括 ASP.NET Core)。Internet Information Services (IIS) is a flexible, secure and manageable Web Server for hosting web apps, including ASP.NET Core. 需要 .NET 5 和 Windows 10 版本 20300.1000 或更高版本,才能将 gRPC 服务与 IIS 一起托管,这可能需要使用 Windows 预览体验成员内部版本。.NET 5 and Windows 10 Build 20300.1000 or later are required to host gRPC services with IIS, which may require the use of a Windows Insider build.

必须将 IIS 配置为使用 TLS 和 HTTP/2。IIS must be configured to use TLS and HTTP/2. 有关详细信息,请参阅 在 IIS 中将 ASP.NET Core 和 HTTP/2 结合使用For more information, see 在 IIS 中将 ASP.NET Core 和 HTTP/2 结合使用.

HTTP.sysHTTP.sys

HTTP.sys 是仅在 Windows 上运行的适用于 ASP.NET Core 的 Web 服务器。HTTP.sys is a web server for ASP.NET Core that only runs on Windows. 需要 .NET 5 和 Windows 10 版本 19529 或更高版本,才能将 gRPC 服务与 HTTP.sys 托管,这可能需要使用 Windows 预览体验成员内部版本。.NET 5 and Windows 10 Build 19529 or later are required to host gRPC services with HTTP.sys, which may require the use of a Windows Insider build.

必须将 HTTP.sys 配置为使用 TLS 和 HTTP/2。HTTP.sys must be configured to use TLS and HTTP/2. 有关详细信息,请参阅 HTTP.sys Web 服务器 HTTP/2 支持For more information, see HTTP.sys web server HTTP/2 support.

Kestrel

Kestrel 是一个跨平台的适用于 ASP.NET Core 的 Web 服务器。Kestrel is a cross-platform web server for ASP.NET Core. Kestrel 提供了最佳性能和内存利用率,但它没有 HTTP.sys 中的某些高级功能,如端口共享。Kestrel provides the best performance and memory utilization, but it doesn't have some of the advanced features in HTTP.sys such as port sharing.

Kestrel gRPC 终结点:Kestrel gRPC endpoints:

HTTP/2HTTP/2

gRPC 需要 HTTP/2。gRPC requires HTTP/2. 适用于 ASP.NET Core 的 gRPC 验证 HttpRequest.ProtocolHTTP/2gRPC for ASP.NET Core validates HttpRequest.Protocol is HTTP/2.

Kestrel 在大多数新式操作系统上支持 HTTP/2Kestrel supports HTTP/2 on most modern operating systems. 默认情况下,Kestrel 终结点配置为支持 HTTP/1.1 和 HTTP/2 连接。Kestrel endpoints are configured to support HTTP/1.1 and HTTP/2 connections by default.

TLSTLS

用于 gRPC 的 Kestrel 终结点应使用 TLS 进行保护。Kestrel endpoints used for gRPC should be secured with TLS. 在开发环境中,当存在 ASP.NET Core 开发证书时,会在 https://localhost:5001 自动创建使用 TLS 进行保护的终结点。In development, an endpoint secured with TLS is automatically created at https://localhost:5001 when the ASP.NET Core development certificate is present. 不需要任何配置。No configuration is required. https 前缀验证 Kestrel 终结点是否正在使用 TLS。An https prefix verifies the Kestrel endpoint is using TLS.

在生产环境中,必须显式配置 TLS。In production, TLS must be explicitly configured. 以下 appsettings.json 示例中提供了使用 TLS 进行保护的 HTTP/2 终结点:In the following appsettings.json example, an HTTP/2 endpoint secured with TLS is provided:

{
  "Kestrel": {
    "Endpoints": {
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Protocols": "Http2",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      }
    }
  }
}

或者,可以在 Program.cs 中配置 Kestrel 终结点:Alternatively, Kestrel endpoints can be configured in Program.cs:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(options =>
            {
                options.Listen(IPAddress.Any, 5001, listenOptions =>
                {
                    listenOptions.Protocols = HttpProtocols.Http2;
                    listenOptions.UseHttps("<path to .pfx file>", 
                        "<certificate password>");
                });
            });
            webBuilder.UseStartup<Startup>();
        });

协议协商Protocol negotiation

TLS 的用途不仅限于保护通信。TLS is used for more than securing communication. 当终结点支持多个协议时,TLS 应用程序层协议协商 (ALPN) 握手可用于协商客户端与服务器之间的连接协议。The TLS Application-Layer Protocol Negotiation (ALPN) handshake is used to negotiate the connection protocol between the client and the server when an endpoint supports multiple protocols. 此协商确定连接是使用 HTTP/1.1 还是 HTTP/2。This negotiation determines whether the connection uses HTTP/1.1 or HTTP/2.

如果在不使用 TLS 的情况下配置了 HTTP/2 终结点,则必须将终结点的 ListenOptions.Protocols 设置为 HttpProtocols.Http2If an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2. 如果没有 TLS,则无法使用具有多个协议(例如 HttpProtocols.Http1AndHttp2)的终结点,因为没有协商。An endpoint with multiple protocols (for example, HttpProtocols.Http1AndHttp2) can't be used without TLS because there's no negotiation. 到不安全终结点的所有连接均默认为 HTTP/1.1,且 gRPC 调用会失败。All connections to the unsecured endpoint default to HTTP/1.1, and gRPC calls fail.

有关使用 Kestrel 启用 HTTP/2 和 TLS 的详细信息,请参阅 Kestrel 终结点配置For more information on enabling HTTP/2 and TLS with Kestrel, see Kestrel endpoint configuration.

备注

macOS 不支持 ASP.NET Core gRPC 及 TLS。macOS doesn't support ASP.NET Core gRPC with TLS. 在 macOS 上成功运行 gRPC 服务需要其他配置。Additional configuration is required to successfully run gRPC services on macOS. 有关详细信息,请参阅无法在 macOS 上启用 ASP.NET Core gRPC 应用For more information, see Unable to start ASP.NET Core gRPC app on macOS.

与 ASP.NET Core API 集成Integration with ASP.NET Core APIs

gRPC 服务对 ASP.NET Core 功能(如依赖关系注入 (DI)日志记录)具有完全访问权限。gRPC services have full access to the ASP.NET Core features such as Dependency Injection (DI) and Logging. 例如,服务实现可以通过构造函数从 DI 容器解析记录器服务:For example, the service implementation can resolve a logger service from the DI container via the constructor:

public class GreeterService : Greeter.GreeterBase
{
    public GreeterService(ILogger<GreeterService> logger)
    {
    }
}

默认情况下,gRPC 服务实现可以解析具有任意生存期(单一实例、范围内或暂时)的其他 DI 服务。By default, the gRPC service implementation can resolve other DI services with any lifetime (Singleton, Scoped, or Transient).

解析 gRPC 方法中的 HttpContextResolve HttpContext in gRPC methods

gRPC API 提供对某些 HTTP/2 消息数据(如方法、主机、标头和尾部)的访问权限。The gRPC API provides access to some HTTP/2 message data, such as the method, host, header, and trailers. 访问是通过传递到每个 gRPC 方法的 ServerCallContext 参数进行的:Access is through the ServerCallContext argument passed to each gRPC method:

public class GreeterService : Greeter.GreeterBase
{
    public override Task<HelloReply> SayHello(
        HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply
        {
            Message = "Hello " + request.Name
        });
    }
}

ServerCallContext 不提供对所有 ASP.NET API 中 HttpContext 的完全访问权限。ServerCallContext doesn't provide full access to HttpContext in all ASP.NET APIs. GetHttpContext 扩展方法提供对在 ASP.NET API 中表示基础 HTTP/2 消息的 HttpContext 的完全访问权限:The GetHttpContext extension method provides full access to the HttpContext representing the underlying HTTP/2 message in ASP.NET APIs:

public class GreeterService : Greeter.GreeterBase
{
    public override Task<HelloReply> SayHello(
        HelloRequest request, ServerCallContext context)
    {
        var httpContext = context.GetHttpContext();
        var clientCertificate = httpContext.Connection.ClientCertificate;

        return Task.FromResult(new HelloReply
        {
            Message = "Hello " + request.Name + " from " + clientCertificate.Issuer
        });
    }
}

其他资源Additional resources