系列文章目录
目录
系列文章目录
前言
0.1 主要应用场景
0.2 核心优势特性
一、快速入门
1.1 先决条件
1.1.1 gRPC
1.1.2 gRPC 工具
1.2 下载示例代码
1.3 运行一个 gRPC 应用程序
1.4 更新gRPC服务
1.5 生成 gRPC 代码
1.6 更新并运行应用程序
1.6.1 更新服务器
1.6.2 更新客户端
1.6.3 运行!
二、基础教程
2.1 为何选择gRPC?
2.2 示例代码与环境配置
2.3 定义服务
2.4 生成客户端和服务器代码
2.4.1 生成具有自定义包路径的 gRPC 接口
2.5 创建服务器
2.5.1 实现 RouteGuide
2.5.1.1 简单 RPC
2.5.1.2 响应流式RPC
2.5.1.3 请求流式 RPC
2.5.1.4 双向流式RPC
2.5.1.5 启动服务器
2.6 创建客户端
2.6.1 创建存根
2.6.2 调用服务方法
2.6.2.1 简单RPC
2.6.2.2 响应流式RPC
2.6.2.3 请求流式RPC
2.6.2.4 双向流式RPC
2.7 试试看!
三、ALTS 身份验证
3.1 概述
3.2 采用 ALTS 传输安全协议的 gRPC 客户端
3.3 采用ALTS传输安全协议的gRPC服务器
四、生成的代码引用
4.1 示例
4.2 代码元素
4.2.1 存根类
4.2.2 Servicer类
4.2.3 注册函数
前言
gRPC 是一个现代开源的高性能远程过程调用(RPC)框架,可在任何环境中运行。它能高效连接数据中心内及跨数据中心的服务,并支持可插拔的负载均衡、追踪、健康检查和身份验证功能。它同样适用于分布式计算的最后一公里,将设备、移动应用和浏览器连接至后端服务。

0.1 主要应用场景
- 高效连接微服务架构中的多语言服务
- 连接移动设备、浏览器客户端与后端服务
- 生成高效客户端库
0.2 核心优势特性
- 支持11种语言的原生客户端库
- 高效传输与简洁的服务定义框架
- 基于HTTP/2传输的双向流式传输
- 可插拔认证、追踪、负载均衡与健康检查
**一、**快速入门
本指南通过一个简单的可运行示例,帮助您在 Python 中开始使用 gRPC。
1.1 先决条件
- Python 3.7 或更高版本
- pip 版本 9.0.1 或更高版本
如有必要,请升级您的 pip 版本:
python -m pip install --upgrade pip
1.1.1 gRPC
安装 gRPC:
或者,要系统范围安装:
sudo python -m pip install grpcio
1.1.2 gRPC 工具
Python 的 gRPC 工具包含协议缓冲编译器 protoc 以及用于从 .proto 服务定义生成服务器和客户端代码的专用插件。在本快速入门示例的前半部分,我们已从 helloworld.proto 生成服务器和客户端存根代码,但后续快速入门、后续教程以及您自己的项目仍需使用这些工具。
安装 gRPC 工具请执行:
python -m pip install grpcio-tools
1.2 下载示例代码
您需要本地副本的示例代码才能完成本快速入门指南。请从我们的 GitHub 仓库下载示例代码(以下命令会克隆整个仓库,但您只需示例代码即可完成本快速入门及其他教程):
1# Clone the repository to get the example code: 2git clone -b v1.74.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc 3# Navigate to the "hello, world" Python example: 4cd grpc/examples/python/helloworld
1.3 运行一个 gRPC 应用程序
从 examples/python/helloworld 目录:
- 运行服务器:
python greeter_server.py - 在另一个终端中运行客户端:
python greeter_client.py
恭喜!您刚刚成功运行了一个基于gRPC的客户端-服务器应用程序。
1.4 更新gRPC服务
现在让我们看看如何在服务器端添加一个额外方法供客户端调用,从而更新应用程序。我们的gRPC服务采用协议缓冲区定义;关于如何在.proto文件中定义服务,您可查阅《gRPC入门》和《基础教程》获取更多信息。当前您只需了解:服务器端和客户端“存根”均包含一个SayHello RPC方法,该方法接收客户端的HelloRequest参数并返回服务器的HelloReply响应,其定义如下:
1// The greeting service definition. 2service Greeter { 3 // Sends a greeting 4 rpc SayHello (HelloRequest) returns (HelloReply) {} 5} 6 7// The request message containing the user's name. 8message HelloRequest { 9 string name = 1; 10} 11 12// The response message containing the greetings 13message HelloReply { 14 string message = 1; 15}
让我们更新这个文件,使 Greeter 服务拥有两个方法。编辑 examples/protos/helloworld.proto 文件,并添加一个新的 SayHelloAgain 方法,其请求和响应类型与原有方法相同:
1// The greeting service definition. 2service Greeter { 3 // Sends a greeting 4 rpc SayHello (HelloRequest) returns (HelloReply) {} 5 // Sends another greeting 6 rpc SayHelloAgain (HelloRequest) returns (HelloReply) {} 7} 8 9// The request message containing the user's name. 10message HelloRequest { 11 string name = 1; 12} 13 14// The response message containing the greetings 15message HelloReply { 16 string message = 1; 17}
记得保存文件!
1.5 生成 gRPC 代码
接下来,我们需要更新应用程序使用的 gRPC 代码,使其采用新的服务定义。
在 examples/python/helloworld 目录下运行:
python -m grpc_tools.protoc -I../../protos --python_out=. --pyi_out=. --grpc_python_out=. ../../protos/helloworld.proto
这将重新生成包含生成的请求和响应类的 helloworld_pb2.py 文件,以及包含生成的客户端和服务器类的 helloworld_pb2_grpc.py 文件。
1.6 更新并运行应用程序
我们现在拥有新生成的服务器和客户端代码,但仍需在示例应用程序的人工编写部分实现并调用新方法。
1.6.1 更新服务器
在同一目录下打开greeter_server.py文件。按以下方式实现新方法:
1class Greeter(helloworld_pb2_grpc.GreeterServicer): 2 3 def SayHello(self, request, context): 4 return helloworld_pb2.HelloReply(message=f"Hello, {request.name}!") 5 6 def SayHelloAgain(self, request, context): 7 return helloworld_pb2.HelloReply(message=f"Hello again, {request.name}!") 8...
1.6.2 更新客户端
在同一目录下,打开greeter_client.py文件。调用新方法时如下所示:
1def run(): 2 with grpc.insecure_channel('localhost:50051') as channel: 3 stub = helloworld_pb2_grpc.GreeterStub(channel) 4 response = stub.SayHello(helloworld_pb2.HelloRequest(name='you')) 5 print("Greeter client received: " + response.message) 6 response = stub.SayHelloAgain(helloworld_pb2.HelloRequest(name='you')) 7 print("Greeter client received: " + response.message)
1.6.3 运行!
就像我们之前做的那样,从 examples/python/helloworld 目录:
- 运行服务器:
python greeter_server.py - 在另一个终端中运行客户端:
python greeter_client.py
二、基础教程
Python中gRPC的基础教程介绍。
本教程为Python程序员提供gRPC入门指南。
通过实践本示例,您将学会:
- 在.proto文件中定义服务
- 使用协议缓冲编译器生成服务器和客户端代码
- 运用Python gRPC API编写服务的简单客户端与服务器
本教程假设您已阅读《gRPC入门指南》并熟悉协议缓冲区。更多内容可参阅proto3语言指南和Python生成的代码指南。
2.1 为何选择gRPC?
我们的示例是一个简单的路线映射应用程序,允许客户端获取路线沿途设施信息、创建路线摘要,并与服务器及其他客户端交换路线信息(如交通更新)。
借助 gRPC,我们只需在 .proto 文件中定义服务一次,即可为 gRPC 支持的任意语言生成客户端和服务器。这些程序既可在大型数据中心的服务器环境运行,也能在个人平板设备上运行——不同语言和环境间的通信复杂性均由 gRPC 自动处理。同时还能享受协议缓冲区带来的所有优势,包括高效序列化、简洁的接口描述语言(IDL)以及便捷的接口更新机制。
2.2 示例代码与环境配置
本教程示例代码位于 grpc/grpc/examples/python/route_guide。下载示例请执行以下命令克隆 grpc 仓库:
git clone -b v1.74.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
然后将当前目录切换到仓库中的 examples/python/route_guide 目录:
cd grpc/examples/python/route_guide
你还需要安装相关工具来生成服务器和客户端接口代码——如果尚未安装,请按照快速入门中的设置说明操作。
2.3 定义服务
(正如《gRPC入门》所述)第一步是使用协议缓冲区定义gRPC服务及方法请求/响应类型。完整.proto文件可参见examples/protos/route_guide.proto。
定义服务时,需在.proto文件中指定命名服务:
1service RouteGuide { 2 // (Method definitions not shown) 3}
然后在服务定义中定义 RPC 方法,指定其请求和响应类型。gRPC 允许定义四种服务方法,RouteGuide 服务中均使用了这些方法:
- 一种简单的 RPC,客户端通过存根向服务器发送请求并等待响应返回,就像普通函数调用一样。
1// Obtains the feature at a given position. 2rpc GetFeature(Point) returns (Feature) {}
- 响应流式RPC中,客户端向服务器发送请求后会获得一个流,用于读取返回的消息序列。客户端从返回的流中读取消息直至消息耗尽。如示例所示,通过在响应类型前添加stream关键字即可指定响应流式方法。
1// Obtains the Features available within the given Rectangle. Results are 2// streamed rather than returned at once (e.g. in a response message with a 3// repeated field), as the rectangle may cover a large area and contain a 4// huge number of features. 5rpc ListFeatures(Rectangle) returns (stream Feature) {}
- 请求流式RPC中,客户端将消息序列写入并发送至服务器,同样使用提供的流。客户端完成消息写入后,将等待服务器读取全部消息并返回响应。通过在请求类型前添加stream关键字即可指定请求流式方法。
1// Accepts a stream of Points on a route being traversed, returning a 2// RouteSummary when traversal is completed. 3rpc RecordRoute(stream Point) returns (RouteSummary) {}
- 一种双向流式RPC,双方均通过读写流发送消息序列。两个流独立运行,因此客户端和服务器可按任意顺序读写:例如服务器可等待接收所有客户端消息后再写入响应,也可交替读写消息,或采用其他读写组合方式。每个流中的消息顺序均得到保留。要指定此类方法,需在请求和响应前均添加 stream 关键字。
1// Accepts a stream of RouteNotes sent while a route is being traversed, 2// while receiving other RouteNotes (e.g. from other users). 3rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
您的 .proto 文件还包含了服务方法中所有请求和响应类型的协议缓冲区消息类型定义——例如,以下是 Point 消息类型:
1// Points are represented as latitude-longitude pairs in the E7 representation 2// (degrees multiplied by 10**7 and rounded to the nearest integer). 3// Latitudes should be in the range +/- 90 degrees and longitude should be in 4// the range +/- 180 degrees (inclusive). 5message Point { 6 int32 latitude = 1; 7 int32 longitude = 2; 8}
2.4 生成客户端和服务器代码
接下来,您需要从 .proto 服务定义中生成 gRPC 客户端和服务器接口。
首先,安装 grpcio-tools 包:
使用以下命令生成 Python 代码:
python -m grpc_tools.protoc -I../../protos --python_out=. --pyi_out=. --grpc_python_out=. ../../protos/route_guide.proto
请注意,由于我们在示例目录中已提供生成的代码版本,执行此命令将重新生成相应文件而非创建新文件。生成的代码文件名为 route_guide_pb2.py 和 route_guide_pb2_grpc.py,包含:
- route_guide.proto 中定义的消息类
- route_guide.proto 中定义的服务类
- RouteGuideStub(客户端可用于调用 RouteGuide RPC)
- RouteGuideServicer(定义 RouteGuide 服务的实现接口)
- route_guide.proto 中定义的服务函数
- add_RouteGuideServicer_to_server(将 RouteGuideServicer 添加至 grpc.Server)
注释
pb2 中的 2 表示生成的代码遵循 Protocol Buffers Python API 第 2 版。第 1 版已废弃。这与 Protocol Buffers 语言版本无关,后者由 .proto 文件中的 syntax = “proto3” 或 syntax = “proto2” 指定。
2.4.1 生成具有自定义包路径的 gRPC 接口
若要生成具有自定义包路径的 gRPC 客户端接口,可使用 grpc_tools.protoc 命令配合 -I 参数。此方法允许您为生成的文件指定自定义包名称。
以下是生成具有自定义包路径的 gRPC 客户端接口的示例命令:
1python -m grpc_tools.protoc -Igrpc/example/custom/path=../../protos \ 2 --python_out=. --grpc_python_out=. \ 3 ../../protos/route_guide.proto
生成的文件将放置在 ./grpc/example/custom/path/ 目录下:
- ./grpc/example/custom/path/route_guide_pb2.py
- ./grpc/example/custom/path/route_guide_pb2_grpc.py
通过此配置,生成的route_guide_pb2_grpc.py文件将正确导入自定义包结构中的protobuf定义,如下所示:
import grpc.example.custom.path.route_guide_pb2 as route_guide_pb2
通过这种方法,您可以确保文件在指定的包路径下正确调用彼此。该方法允许您为gRPC客户端接口维护自定义的包结构。
2.5 创建服务器
首先了解如何创建 RouteGuide 服务器。若您仅需创建 gRPC 客户端,可跳过本节直接进入创建客户端部分(不过您可能仍会发现它很有趣!)。
创建并运行 RouteGuide 服务器包含两项工作:
- 实现由服务定义生成的服务接口,并添加执行服务实际“工作”的函数。
- 运行 gRPC 服务器以监听客户端请求并传输响应。
示例 RouteGuide 服务器位于 examples/python/route_guide/route_guide_server.py。
2.5.1 实现 RouteGuide
route_guide_server.py 包含 RouteGuideServicer 类,该类继承自生成的 route_guide_pb2_grpc.RouteGuideServicer 类:
1# RouteGuideServicer provides an implementation of the methods of the RouteGuide service. 2class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
RouteGuideServicer 实现了所有 RouteGuide 服务方法。
2.5.1.1 简单 RPC
首先来看最简单的类型 GetFeature,它仅从客户端获取一个点,然后从数据库中返回对应的特征信息,并封装在 Feature 中。
1def GetFeature(self, request, context): 2 feature = get_feature(self.db, request) 3 if feature is None: 4 return route_guide_pb2.Feature(name="", location=request) 5 else: 6 return feature
该方法接收一个用于RPC的route_guide_pb2.Point请求,以及一个提供RPC特定信息(如超时限制)的grpc.ServicerContext对象。它返回一个route_guide_pb2.Feature响应。
2.5.1.2 响应流式RPC
现在来看下一个方法。ListFeatures是一个响应流式RPC,用于向客户端发送多个特征。
1def ListFeatures(self, request, context): 2 left = min(request.lo.longitude, request.hi.longitude) 3 right = max(request.lo.longitude, request.hi.longitude) 4 top = max(request.lo.latitude, request.hi.latitude) 5 bottom = min(request.lo.latitude, request.hi.latitude) 6 for feature in self.db: 7 if ( 8 feature.location.longitude >= left 9 and feature.location.longitude <= right 10 and feature.location.latitude >= bottom 11 and feature.location.latitude <= top 12 ): 13 yield feature
此处请求消息为 route_guide_pb2.Rectangle 对象,客户端希望在其内部查找特征。该方法不会返回单一响应,而是返回零个或多个响应。
2.5.1.3 请求流式 RPC
请求流式方法 RecordRoute 使用请求值迭代器,并返回单个响应值。
1def RecordRoute(self, request_iterator, context): 2 point_count = 0 3 feature_count = 0 4 distance = 0.0 5 prev_point = None 6 7 start_time = time.time() 8 for point in request_iterator: 9 point_count += 1 10 if get_feature(self.db, point): 11 feature_count += 1 12 if prev_point: 13 distance += get_distance(prev_point, point) 14 prev_point = point 15 16 elapsed_time = time.time() - start_time 17 return route_guide_pb2.RouteSummary( 18 point_count=point_count, 19 feature_count=feature_count, 20 distance=int(distance), 21 elapsed_time=int(elapsed_time), 22 )
2.5.1.4 双向流式RPC
最后,我们来看双向流式方法RouteChat。
1def RouteChat(self, request_iterator, context): 2 prev_notes = [] 3 for new_note in request_iterator: 4 for prev_note in prev_notes: 5 if prev_note.location == new_note.location: 6 yield prev_note 7 prev_notes.append(new_note)
该方法的语义结合了请求流式处理方法和响应流式处理方法的特性。它接收请求值的迭代器,自身则作为响应值的迭代器。
2.5.1.5 启动服务器
在实现所有 RouteGuide 方法后,下一步是启动 gRPC 服务器,以便客户端能够实际使用您的服务:
1def serve(): 2 server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) 3 route_guide_pb2_grpc.add_RouteGuideServicer_to_server(RouteGuideServicer(), server) 4 server.add_insecure_port("[::]:50051") 5 server.start() 6 server.wait_for_termination()
服务器 start() 方法是非阻塞的。将创建一个新线程来处理请求。调用 server.start() 的线程在此期间通常没有其他工作可做。这种情况下,可调用 server.wait_for_termination() 使调用线程在服务器终止前保持干净阻塞状态。
2.6 创建客户端
完整的示例客户端代码详见examples/python/route_guide/route_guide_client.py。
2.6.1 创建存根
调用服务方法前需先创建存根。
我们实例化route_guide_pb2_grpc模块中的RouteGuideStub类,该类由.proto文件生成。
1channel = grpc.insecure_channel('localhost:50051') 2stub = route_guide_pb2_grpc.RouteGuideStub(channel)
2.6.2 调用服务方法
对于返回单一响应的RPC方法(即“响应单态”方法),gRPC Python同时支持同步(阻塞)和异步(非阻塞)控制流语义。对于响应流式RPC方法,调用会立即返回响应值的迭代器。调用该迭代器的next()方法将阻塞,直至迭代器可返回响应。
2.6.2.1 简单RPC
对简单RPC方法GetFeature的同步调用几乎与调用本地方法同样简单。RPC调用会等待服务器响应,最终返回响应或抛出异常:
feature = stub.GetFeature(point)
对 GetFeature 的异步调用类似,但如同在线程池中异步调用本地方法:
1feature_future = stub.GetFeature.future(point) 2feature = feature_future.result()
2.6.2.2 响应流式RPC
调用响应流式ListFeatures与处理序列类型类似:
for feature in stub.ListFeatures(rectangle):
2.6.2.3 请求流式RPC
调用请求流式RecordRoute类似于向本地方法传递迭代器。如同上述仅返回单个响应的简单RPC,它既可同步调用也可异步调用:
route_summary = stub.RecordRoute(point_iterator)
1route_summary_future = stub.RecordRoute.future(point_iterator) 2route_summary = route_summary_future.result()
2.6.2.4 双向流式RPC
调用双向流式RouteChat时(与服务端情况相同),请求流式与响应流式的语义会同时生效:
for received_route_note in stub.RouteChat(sent_route_note_iterator):
2.7 试试看!
运行服务器:
python route_guide_server.py
从另一个终端运行客户端:
python route_guide_client.py
三、ALTS 身份验证
使用应用层传输安全(ALTS)在 Python 中实现 gRPC 身份验证的概述。
3.1 概述
应用层传输安全(ALTS)是由谷歌开发的双向认证与传输加密系统,用于保障谷歌基础设施内的RPC通信安全。ALTS与双向TLS类似,但经过专门设计和优化以满足谷歌生产环境的需求。更多详情请参阅ALTS白皮书。
gRPC中的ALTS具备以下特性:
- 创建以ALTS作为传输安全协议的gRPC服务器与客户端。
- ALTS连接提供端到端隐私保护与完整性保障。
- 应用程序可访问对等方信息(如对等服务账户)。
- 支持客户端授权与服务器授权机制。
- 启用ALTS仅需极少代码修改。
gRPC用户只需少量代码即可配置应用程序使用ALTS作为传输安全协议。
请注意,若应用程序在 Compute Engine 或 Google Kubernetes Engine (GKE) 上运行,ALTS 将实现全部功能。
3.2 采用 ALTS 传输安全协议的 gRPC 客户端
gRPC 客户端可使用 ALTS 凭证连接服务器,如下代码片段所示:
1import grpc 2 3channel_creds = grpc.alts_channel_credentials() 4channel = grpc.secure_channel(address, channel_creds)
3.3 采用ALTS传输安全协议的gRPC服务器
gRPC服务器可使用ALTS凭据允许客户端连接,如下所示:
1import grpc 2 3server = grpc.server(futures.ThreadPoolExecutor()) 4server_creds = grpc.alts_server_credentials() 5server.add_secure_port(server_address, server_creds)
四、生成的代码引用
gRPC Python依赖协议缓冲区编译器(protoc)生成代码。它通过插件将普通protoc生成的代码补充为包含gRPC特异性代码的代码。对于包含 gRPC 服务的 .proto 服务描述文件,普通 protoc 生成的代码会被合成到 _pb2.py 文件中,而 gRPC 专属代码则存放在 _pb2_grpc.py 文件里。后者作为 Python 模块会导入前者。本页重点介绍生成的代码中 gRPC 专属的子集。
4.1 示例
考虑以下 FortuneTeller proto 服务:
1service FortuneTeller { 2 // Returns the horoscope and zodiac sign for the given month and day. 3 rpc TellFortune(HoroscopeRequest) returns (HoroscopeResponse) { 4 // errors: invalid month or day, fortune unavailable 5 } 6 7 // Replaces the fortune for the given zodiac sign with the provided one. 8 rpc SuggestFortune(SuggestionRequest) returns (SuggestionResponse) { 9 // errors: invalid zodiac sign 10 } 11}
当服务被编译时,gRPC协议插件会生成类似以下的_pb2_grpc.py文件:
1import grpc 2 3import fortune_pb2 4 5class FortuneTellerStub(object): 6 7 def __init__(self, channel): 8 """Constructor. 9 10 Args: 11 channel: A grpc.Channel. 12 """ 13 self.TellFortune = channel.unary_unary( 14 '/example.FortuneTeller/TellFortune', 15 request_serializer=fortune_pb2.HoroscopeRequest.SerializeToString, 16 response_deserializer=fortune_pb2.HoroscopeResponse.FromString, 17 ) 18 self.SuggestFortune = channel.unary_unary( 19 '/example.FortuneTeller/SuggestFortune', 20 request_serializer=fortune_pb2.SuggestionRequest.SerializeToString, 21 response_deserializer=fortune_pb2.SuggestionResponse.FromString, 22 ) 23 24 25class FortuneTellerServicer(object): 26 27 def TellFortune(self, request, context): 28 """Returns the horoscope and zodiac sign for the given month and day. 29 errors: invalid month or day, fortune unavailable 30 """ 31 context.set_code(grpc.StatusCode.UNIMPLEMENTED) 32 context.set_details('Method not implemented!') 33 raise NotImplementedError('Method not implemented!') 34 35 def SuggestFortune(self, request, context): 36 """Replaces the fortune for the given zodiac sign with the provided 37one. 38 errors: invalid zodiac sign 39 """ 40 context.set_code(grpc.StatusCode.UNIMPLEMENTED) 41 context.set_details('Method not implemented!') 42 raise NotImplementedError('Method not implemented!') 43 44 45def add_FortuneTellerServicer_to_server(servicer, server): 46 rpc_method_handlers = { 47 'TellFortune': grpc.unary_unary_rpc_method_handler( 48 servicer.TellFortune, 49 request_deserializer=fortune_pb2.HoroscopeRequest.FromString, 50 response_serializer=fortune_pb2.HoroscopeResponse.SerializeToString, 51 ), 52 'SuggestFortune': grpc.unary_unary_rpc_method_handler( 53 servicer.SuggestFortune, 54 request_deserializer=fortune_pb2.SuggestionRequest.FromString, 55 response_serializer=fortune_pb2.SuggestionResponse.SerializeToString, 56 ), 57 } 58 generic_handler = grpc.method_handlers_generic_handler( 59 'example.FortuneTeller', rpc_method_handlers) 60 server.add_generic_rpc_handlers((generic_handler,))
4.2 代码元素
生成的gRPC代码首先导入grpc包和由protoc合成的普通_pb2模块,该模块定义了非gRPC特有的代码元素,例如对应协议缓冲区消息的类以及反射使用的描述符。
对于.proto文件中的每个服务Foo,会生成三个主要元素:
- 存根类:FooStub,用于客户端连接gRPC服务。
- 服务实现类:FooServicer,用于服务器端实现gRPC服务。
- 注册函数:add_FooServicer_to_server,用于将服务实现类注册到grpc.Server对象。
4.2.1 存根类
生成的Stub类供gRPC客户端使用。其构造函数接收 grpc.Channel 对象并初始化存根。对于服务中的每个方法,初始化器都会在存根对象中添加同名属性。根据 RPC 类型(单一调用或流式调用),该属性的值将分别是 UnaryUnaryMultiCallable、UnaryStreamMultiCallable、StreamUnaryMultiCallable 或 StreamStreamMultiCallable 类型的可调用对象。
4.2.2 Servicer类
针对每个服务,系统会生成Servicer类作为服务实现的基类。服务中的每个方法都会在Servicer类中生成对应函数,需用服务实现代码覆盖该函数。原生.proto文件中代码元素的注释将作为文档字符串出现在生成的Python代码中。
4.2.3 注册函数
为每个服务生成一个函数,用于将实现该服务的Servicer对象注册到grpc.Server对象上,以便服务器将查询路由至对应服务器。该函数接受两个参数:实现Servicer的对象(通常是上述生成的Servicer代码元素子类的实例)以及grpc.Server对象。
《gRPC Python 详细入门教程(一)》 是转载文章,点击查看原文。
