gRPC接收流式响应时报'NoneType对象不是迭代器'错误如何解决?
错误根因分析
你最初判断问题出在客户端是错误的,该报错的根源在服务端接口实现:
gRPC服务端流式接口要求处理方法必须返回可迭代对象(如生成器、Result实例列表等),如果你的服务端GetServerClassification方法没有显式返回可迭代对象(Python函数默认返回None),或显式返回了None,服务端在迭代响应时就会抛出该错误,再将异常传递到客户端。
错误的服务端实现示例
# 错误实现示例 class VideoClassifierServicer(mec_ar_pb2_grpc.VideoClassifierServicer): def GetServerClassification(self, request, context): # 仅处理了请求逻辑,没有返回可迭代对象,默认返回None img_data = request.image width = request.width # 缺失yield返回/返回可迭代对象的逻辑
正确的服务端实现示例
服务端流式接口需要用yield逐次返回Result实例,或返回包含Result实例的可迭代对象:
# 正确实现示例 class VideoClassifierServicer(mec_ar_pb2_grpc.VideoClassifierServicer): def GetServerClassification(self, request, context): # 处理图片得到检测结果列表 detect_results = your_image_classify_logic(request.image, request.width, request.heigth) # 逐次yield返回结果 for res in detect_results: yield mec_ar_pb2.Result( id=res["id"], x1=res["x1"], x2=res["x2"], y1=res["y1"], y2=res["y2"], label=res["label"], confidence=res["confidence"] )
排查步骤
- 检查服务端
GetServerClassification方法的所有逻辑分支,确认没有显式返回None,也不会因为缺省逻辑默认返回None - 如果方法内有异常捕获逻辑,确认异常分支需要先通过
context.set_code()、context.set_details()设置错误状态,再终止返回,不要直接返回None - 你当前的客户端代码完全正确,
_MultiThreadedRendezvous是gRPC Python客户端流式响应的标准类型,遍历逻辑不需要做任何修改
内容的提问来源于stack exchange,提问作者Andrea Fresa
相关产品推荐
相关产品推荐

