定义服务
第一步是使用 protocol buffers 定义一个 gRPC 服务和其方法的请求、响应类型。
完整 .proto
文件内容在 routeguide/route_guide.proto
。
// Copyright 2015 gRPC authors.
syntax = "proto3";
option go_package = "google.golang.org/grpc/examples/route_guide/routeguide";
option java_multiple_files = true;
option java_package = "io.grpc.examples.routeguide";
option java_outer_classname = "RouteGuideProto";
package routeguide;
service RouteGuide {
rpc GetFeature(Point) returns (Feature) {}
rpc ListFeatures(Rectangle) returns (stream Feature) {}
rpc RecordRoute(stream Point) returns (RouteSummary) {}
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}
// Point 由纬度经度对表示。
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
// 一个纬度经度矩形,由对角线上的两个点 "lo" 和 "hi" 表示。
message Rectangle {
// 矩形的一个角。
Point lo = 1;
// 矩形的另一个角。
Point hi = 2;
}
// 要素指定了给定点的名称。
// 如果无法为要素命名,则名称为空。
message Feature {
// 要素的名称。
string name = 1;
// 要素被检测到的位置。
Point location = 2;
}
// RouteNote 是在给定点发送的消息。
message RouteNote {
// 消息发送的位置。
Point location = 1;
// 要发送的消息。
string message = 2;
}
// RouteSummary 是对 RecordRoute RPC 的响应消息。
//
// 它包含接收到的点数、经过的要素数以及每个点之间距离累加得出的总距离。
message RouteSummary {
// 接收到的点数。
int32 point_count = 1;
// 遍历路线时通过的已知要素数。
int32 feature_count = 2;
// 覆盖的距离(单位:米)。
int32 distance = 3;
// 遍历所花费的时间(单位:秒)。
int32 elapsed_time = 4;
}
要定义一个服务,在你的 .proto
文件中指定一个命名的 service
:
service RouteGuide {
...
}
然后在服务定义内部定义 rpc
方法,指定它们的请求和响应类型。gRPC 允许你定义四种类型的服务方法,这些方法在 RouteGuide
服务中都有使用:
- 简单 RPC,(或者叫一元 RPC):客户端使用 *stub(存根)*将请求发送到服务器,并等待响应返回,就像普通函数调用一样。
// 获取给定点的要素。
rpc GetFeature(Point) returns (Feature) {}
- 服务端流式 RPC:客户端向服务器发送请求并获得一个流以读取一系列消息。客户端从返回的流中读取,直到没有更多的消息为止。如例子所示,通过在响应类型之前放置
stream
关键字来指定服务器端流式方法。
// 获取给定矩形范围内的要素。
// 结果以流的形式返回,而不是即时返回,因为矩形可能覆盖一个大区域并且包含大量要素。
rpc ListFeatures(Rectangle) returns (stream Feature) {}
- 客户端流式RPC:客户端使用提供的流编写一系列消息并将它们发送到服务器。一旦客户端完成编写消息,它就会等待服务器读取所有消息并返回其响应。通过在请求类型之前放置
stream
关键字来指定客户端流式方法。
// 记录遍历路线中的点。当遍历完成时返回 RouteSummary。
rpc RecordRoute(stream Point) returns (RouteSummary) {}
- 双向流式RPC:双方使用读写流发送一系列消息。这两个流操作是独立的,因此客户端和服务端可以按任何顺序读取和写入:例如,服务端可以等待接收所有客户端消息然后编写其响应,或者它可以交替读取消息然后写入消息,或者使用其他组合方式。每个流中消息是有序的。通过在请求和响应之前都放置
stream
关键字来指定此类型的方法。
// 在遍历路线时接收 RouteNote ,同时也发送的一系列 RouteNote。
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
我们的 .proto
文件还包含了用于 rpc
方法使用的所有请求和响应类型的 protocol buffer message(消息)类型定义。
例如,这是 Point
消息类型:
// 点被表示为纬度经度对,以E7表示形式(度乘以10**7并四舍五入到最接近的整数)。
// 纬度应在 +/- 90 度的范围内,经度应在 +/- 180 度的范围内(包含边界数值)。
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
Loading...
> 此处输出代码运行结果