info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET https://localhost:5001/v1/greeter/world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'gRPC - /v1/greeter/{name}'
info: Server.GreeterService[0]
Sending hello to world
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'gRPC - /v1/greeter/{name}'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 1.996ms 200 application/json
批注 gRPC 方法
gRPC 方法必须在支持转码之前使用 HTTP 规则进行注释。 HTTP 规则包括有关如何调用 gRPC 方法的信息,例如 HTTP 方法和路由。
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/v1/greeter/{name}"
继续浏览示例:
使用 SayHello
方法定义 Greeter
服务。 该方法具有使用名称 google.api.http
指定的 HTTP 规则。
可以使用 GET
请求和 /v1/greeter/{name}
路由访问该方法。
请求消息上的 name
字段绑定到路由参数。
许多选项可用于自定义 gRPC 方法如何绑定到 RESTful API。 有关批注 gRPC 方法和自定义 JSON 的详细信息,请参阅为 gRPC JSON 转码配置 HTTP 和 JSON。
流式处理方法
HTTP/2 上的传统 gRPC 支持所有方向的流式处理。 转码仅限于服务器流式处理。 不支持客户端流式处理和双向流式处理方法。
服务器流式处理方法使用以行分隔的 JSON。 使用 WriteAsync
的每条消息都会序列化为 JSON,后跟一个新行。
以下服务器流式处理方法写入三条消息:
public override async Task StreamingFromServer(ExampleRequest request,
IServerStreamWriter<ExampleResponse> responseStream, ServerCallContext context)
for (var i = 1; i <= 3; i++)
await responseStream.WriteAsync(new ExampleResponse { Text = $"Message {i}" });
await Task.Delay(TimeSpan.FromSeconds(1));
客户端接收三个以行分隔的 JSON 对象:
{"Text":"Message 1"}
{"Text":"Message 2"}
{"Text":"Message 3"}
请注意,WriteIndented
JSON 设置不适用于服务器流式处理方法。 整齐打印将新行和空格添加到 JSON,这不能与以行分隔的 JSON 一起使用。
HTTP 协议
.NET SDK 中包含的 ASP.NET Core gRPC 服务模板创建仅针对 HTTP/2 配置的应用。 当应用仅支持传统的 gRPC over HTTP/2 时,HTTP/2 是很好的默认设置。 但是,转码同时适用于 HTTP/1.1 和 HTTP/2。 某些平台(如 UWP 或 Unity)无法使用 HTTP/2。 若要支持所有客户端应用,请将服务器配置为启用 HTTP/1.1 和 HTTP/2。
更新 appsettings.json
中的默认协议:
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
或者,在启动代码中配置 Kestrel 终结点。
在同一端口上启用 HTTP/1.1 和 HTTP/2 需要 TLS 进行协议协商。 有关在 gRPC 应用中配置 HTTP 协议的详细信息,请参阅 ASP.NET Core gRPC 协议协商。
gRPC JSON 转码与 gRPC-Web
转码和 gRPC-Web 都支持从浏览器调用 gRPC 服务。 但是,它们的操作方式是不同的:
gRPC-Web 允许浏览器应用通过 gRPC-Web 客户端和 Protobuf 从浏览器调用 gRPC 服务。 gRPC-Web 需要浏览器应用生成 gRPC 客户端,并且具有快速发送小型 Protobuf 消息的优点。
转码允许浏览器应用调用 gRPC 服务,就像它们是使用 JSON 的 RESTful API 一样。 浏览器应用不需要生成 gRPC 客户端或了解 gRPC 的任何信息。
可以使用浏览器 JavaScript API 调用以前的 Greeter
服务:
var name = nameInput.value;
fetch('/v1/greeter/' + name)
.then((response) => response.json())
.then((result) => {
console.log(result.message);
// Hello world
grpc-gateway
grpc-gateway 是从 gRPC 服务创建 RESTful JSON API 的另一种技术。 它使用相同的 .proto
注释将 HTTP 概念映射到 gRPC 服务。
grpc-gateway 使用代码生成来创建反向代理服务器。 反向代理将 RESTful 调用转换为 gRPC+Protobuf,然后通过 HTTP/2 将调用发送到 gRPC 服务。 这种方法的优点是 gRPC 服务不知道 RESTful JSON API。 任何 gRPC 服务器都可以使用 grpc-gateway。
同时,gRPC JSON 转码在 ASP.NET Core 应用内运行。 它将 JSON 反序列化为 Protobuf 消息,然后直接调用 gRPC 服务。 ASP.NET Core 中的转码为 .NET 应用开发人员提供了以下优势:
复杂性更低:gRPC 服务和映射的 RESTful JSON API 都在同一个 ASP.NET Core 应用外部运行。
性能更佳:转码将 JSON 反序列化为 Protobuf 消息,并直接调用 gRPC 服务。 与对不同的服务器进行新的 gRPC 调用相比,执行此进程内操作时性能有显著的优势。
成本更低:减少了服务器数量,降低了每月托管费用。
如需了解 grpc-gateway 的安装和使用,请参阅 grpc-gateway 自述文件。
为 gRPC JSON 转码 ASP.NET Core 应用配置 HTTP 和 JSON
将 OpenAPI 与 gRPC JSON 转码 ASP.NET Core 应用配合使用
在浏览器应用中使用 gRPC
ASP.NET Core gRPC 应用中的 gRPC-Web