实现 RouteGuide
首先让我们看看如何创建一个 RouteGuide
服务器。
RouteGuide
服务有两个主要部分:
- 实现从我们的服务定义生成的 servicer 接口:执行我们服务的实际“工作”。
- 运行 gRPC 服务器以侦听来自客户端的请求并传输响应。
你可以在 examples/python/route_guide/route_guide_server.py
中找到示例 RouteGuide 服务器代码。
让我们拆解一下它是如何工作的。
route_guide_server.py
有一个 RouteGuideServicer
类。它继承自生成的类 route_guide_pb2_grpc.RouteGuideServicer
:
# RouteGuideServicer 实现 RouteGuide 服务的方法。
class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
RouteGuideServicer
实现了 RouteGuide
服务所有的方法。
简单 RPC
让我们首先看看最简单的类型,GetFeature
。它从客户端获取一个 Point
,并返回其数据库中对应的要素信息 Feature
。
def GetFeature(self, request, context):
feature = get_feature(self.db, request)
if feature is None:
return route_guide_pb2.Feature(name="", location=request)
return feature
该方法接收一个用于 RPC 的 route_guide_pb2.Point
请求对象,和一个用于提供 RPC 特定的超时限制等信息的 grpc.ServicerContext
对象。
它返回一个 route_guide_pb2.Feature
响应。
服务端流式 RPC
ListFeatures
是一个服务端流式 RPC,或者叫响应流式 RPC。它向客户端发送多个 Feature
。
def ListFeatures(self, request, context):
left = min(request.lo.longitude, request.hi.longitude)
right = max(request.lo.longitude, request.hi.longitude)
top = max(request.lo.latitude, request.hi.latitude)
bottom = min(request.lo.latitude, request.hi.latitude)
for feature in self.db:
if (
feature.location.longitude >= left
and feature.location.longitude <= right
and feature.location.latitude >= bottom
and feature.location.latitude <= top
):
yield feature
这里有个 route_guide_pb2.Rectangle
请求 message 用于在其中查找 Feature
。相较于返回单个响应,这里 yield(生成)零个或多个响应。
客户端流式 RPC
客户端流式方法 RecordRoute
使用请求值的迭代器并返回单个响应值。
def RecordRoute(self, request_iterator, context):
point_count = 0
feature_count = 0
distance = 0.0
prev_point = None
start_time = time.time()
for point in request_iterator:
point_count += 1
if get_feature(self.db, point):
feature_count += 1
if prev_point:
distance += get_distance(prev_point, point)
prev_point = point
elapsed_time = time.time() - start_time
return route_guide_pb2.RouteSummary(
point_count=point_count,
feature_count=feature_count,
distance=int(distance),
elapsed_time=int(elapsed_time),
)
双向流式 RPC
最后,让我们看看双向流式 RPC RouteChat
。
def RouteChat(self, request_iterator, context):
prev_notes = []
for new_note in request_iterator:
for prev_note in prev_notes:
if prev_note.location == new_note.location:
yield prev_note
prev_notes.append(new_note)
该方法的语义是服务端流式和客户端流式的结合。它接收一个请求值的迭代器并返回一个响应值的迭代器。
Loading...
> 此处输出代码运行结果