我刚刚开始使用 gRPC,并在阅读入门指南后尝试实现一个简单的 python 服务。但是当我调用我的客户端调用时,python 要求提供上下文参数。为什么我的代码需要提供示例中不需要的上下文对象?
附注我开始尝试创建自己的具体上下文子类,但不确定应该如何实现它。我已经添加了我的开始,但如果可能的话,我真的很感激一个可以使用的例子
谢谢!
原型文件
syntax = "proto2";
package parsefile;
service ParseFile {
rpc SendFile (File) returns (Empty) {}
}
message File {
message MetaData {
optional string file_name = 1;
optional string file_path = 2 [default = '.'];
optional string mime_type = 3 [default = 'application/pdf'];
}
message Source {
optional string title = 1;
optional int32 id = 2;
}
optional MetaData document = 1;
optional Source supplier = 2;
}
message Empty {
}
服务器
from concurrent import futures
import time
import grpc
import parsefile_pb2_grpc
import parsefile_pb2
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
class ParseFileServicer(parsefile_pb2_grpc.ParseFileServicer):
def SendFile(self, request, context):
supplier = request.supplier.title
file_name = request.document.file_name
print('Received {} from {}'.format(file_name, supplier))
return parsefile_pb2.Empty()
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=2))
parsefile_pb2_grpc.add_ParseFileServicer_to_server(
ParseFileServicer, server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
客户
import grpc
import parsefile_pb2_grpc
import parsefile_pb2
def get_file_info():
return parsefile_pb2.File(
document = parsefile_pb2.File.MetaData(
file_name = 'example.txt'
),
supplier = parsefile_pb2.File.Source(
title = 'Example Supplier'
)
)
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = parsefile_pb2_grpc.ParseFileStub(channel)
context = RequestContext()
print('object created')
response = stub.SendFile(get_file_info())
print('File info sent to server')
if __name__ == '__main__':
run()
错误追踪
Traceback (most recent call last): File "parse_client.py", line 60, in <module>
run() File "parse_client.py", line 56, in run
response = stub.SendFile(get_file_info(), 2) File "/Users/davidbowe/.virtualenvs/post/lib/python3.6/site-packages/grpc/_channel.py", line 507, in __call__
return _end_unary_response_blocking(state, call, False, deadline) File "/Users/davidbowe/.virtualenvs/post/lib/python3.6/site-packages/grpc/_channel.py", line 455, in _end_unary_response_bl ocking
raise _Rendezvous(state, None, None, deadline) grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.UNKNOWN, Exception calling application: SendF ile() missing 1 required positional argument: 'context')>
在您的服务器代码中,您缺少用于实例化服务程序对象的括号。你写了...
parsefile_pb2_grpc.add_ParseFileServicer_to_server(ParseFileServicer, server)
应该是:
parsefile_pb2_grpc.add_ParseFileServicer_to_server(ParseFileServicer(), server)
您不需要创建
context
参数,它是由grpc自动创建的。
我遇到这个错误是因为我添加了一个额外的方法。我刚刚将该方法移到了类之外。