简要说明
阅读收获
- 通过 .proto 文件对服务端进行定义
- 通过 protocol buffer 生成服务端和客户端的代码
- 使用 Python gRPC 的接口来完成简单的客户端和服务器交互
面向的读者
已经阅读完 介绍 及 快速入门 相关内容,并熟悉 protocol buffers的书写:
proto3 language guide and Python generated code guide
获取示例代码
示例代码保存在 grpc/grpc/examples/python/route_guide,同时我们可以通过 git 将代码 clone 到我们本地:
$ git clone -b v1.35.0 https://github.com/grpc/grpc
然后将目录切换到:
$ cd grpc/examples/python/route_guide
此时就需要 gRPC 生成的对应工具,有关介绍在 快速入门 有详细说明。
准备工作
定义一个服务
在和 Python 文件夹的同级 protos 文件夹中,有一个 route_guide.proto (examples/protos/route_guide.proto
)。
里面通过如下格式给 server 端定义了一个服务:
service RouteGuide {
// (Method definitions not shown)
}
然后就在 service
修饰的语句块中书写相关的 rpc
方法。
在 RuiteGuide 语句块中,里面分别书写了四种 RPC 的形式(相关介绍在RPC 的生命周期 这一段中有过详细介绍).
- 最简单的 RPC 调用方式,类似于直接调用一个方法:
rpc GetFeature(Point) returns (Feature) {}
- 服务端流式 RPC:当客户端发送一个请求并被接收之后,服务端将返回的响应通过字节流的形式分块进行返回。注意 proto 文件的返回字段需要被 stream 修饰。
// Obtains the Features available within the given Rectangle. Results are
// streamed rather than returned at once (e.g. in a response message with a
// repeated field), as the rectangle may cover a large area and contain a
// huge number of features.
rpc ListFeatures(Rectangle) returns (stream Feature) {}
- 客户端流式 RPC:客户端通过字节流的形式进行请求,然后在服务端全部接收完成之后返回响应信息。
// Accepts a stream of Points on a route being traversed, returning a
// RouteSummary when traversal is completed.
rpc RecordRoute(stream Point) returns (RouteSummary) {}
- 双端流式 RPC:客户端和服务端都通过字节流进行消息的传输,每次发送的字节流顺序都会被记录,此时我们可以对程序进行自定义:即一边接收数据,一边返回信息。
// Accepts a stream of RouteNotes sent while a route is being traversed,
// while receiving other RouteNotes (e.g. from other users).
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
.proto
文件中同样包含了请求和响应的消息类型的定义,例如下面的 Point 消息体:
// Points are represented as latitude-longitude pairs in the E7 representation
// (degrees multiplied by 10**7 and rounded to the nearest integer).
// Latitudes should be in the range +/- 90 degrees and longitude should be in
// the range +/- 180 degrees (inclusive).
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
代码映射
我们可以通过命令行的方式将 proto 文件映射成 Python 代码:
$ python -m grpc_tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/route_guide.proto
此时生成了 route_guide_pb2.py
和 route_guide_pb2_grpc.py
俩文件。
-
定义 messages 的相关内容在 route_guide.proto 文件中。
-
定义 service 相关内容的代码块位于 route_guide.proto,其相关映射的内容在 route_guide_pb2_grpc.py 文件中。
RouteGuideStub
:用来给客户端调用服务端 RouteGuide 接口。RouteGuideServicer(class)
:用来在服务端定义 gRPC 接口。
-
定义相关请求和返回消息的方法位于
route_guide.proto
。add_RouteGuideServicer_to_server
:用来将 server 端所需的接口添加到 server 中去,目的是为了给远程的 client 进行 gRPC 调用。
注意:生成的 Python 文件后缀名有 pb2 的字眼,这个跟 神马 版本没有关系,只是 Google 开发 Protobuf 时内部规定的。、
序列化模块安装
安装 protobuf3-to-dict 包。简单的说就是:
from protobuf3_to_dict import protobuf_to_dict
# 当我们需要将指定对象转化为字典的时候,直接传入即可.
d = protobuf_to_dict(add_resp)
print(d)
具体可以看 Protobuf 篇章中有介绍。
相关概念介绍
在介绍传输方式之前,我们先看下 GRPC 当中 Stub 等常见概念的概念(原文地址):