grpc地址:https://github.com/grpc/grpc
pip install grpcio #gRPC 的安装
pip install protobuf #ProtoBuf 相关的 python 依赖库
pip install grpcio-tools #python grpc 的 protobuf 编译工具
gRPC包括3部分:
使用 protocol buffers去定义 gRPC service 和方法 request 以及 response 的类型,实例程序中helloword方法的.proto
文件
> helloword.proto
// 定义服务.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {} //定义rpc方法
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {} //简单的rpc
}
// 请求的参数name和phone,值为int类型不可重复
message HelloRequest {
string name = 1;
string phone = 2;
}
// 返回的参数message,值为int类型
message HelloReply {
string message = 1;
//string idcard = 2;
}
gRPC 允许你定义4种类型的 service 方法:具体参考
接下来你需要从 .proto 的服务定义中生成 gRPC 客户端和服务器端的接口。你可以通过 protocol buffer 的编译器 protoc 以及一个特殊的 gRPC Python 插件来完成。
python -m grpc_tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/helloworld.proto
运行后根据helloworld.proto
生成2个文件:helloword_pb2.py
和helloword_pb2_grpc.py
helloworld.proto
中的消息类helloworld.proto
中的服务抽象类
class GreeterServicer(object)
:定义了Greeter(helloworld.proto
中service Greeter { }
)的实现接口class GreeterStub(object)
:可以被客户端用来激活 helloword RPCadd_GreeterServicer_to_server(servicer, server)
:将GreeterServicer
添加到服务端创建和运行service可以分为两部分:
.proc
中定义的rpc函数。class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def SayHelloAgain(self, request, context):
return helloworld_pb2.HelloReply(message='Hello Again, %s!' % request.name)
Greeter
是类helloworld_pb2_grpc.GreeterServicer
的子类Greeter
实现helloworld.proto
中service Greeter { }
中定义的rpc函数启动一个gRPC服务器,这样客户端才可以使用服务
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
因为 start() 不会阻塞,如果运行时你的代码没有其它的事情可做,你可能需要循环等待。
def run():
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
# used in circumstances in which the with statement does not fit the needs
# of the code.
with grpc.insecure_channel('localhost:50051') as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel) //创建一个stub
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + response.message)
response = stub.SayHelloAgain(helloworld_pb2.HelloRequest(name='yy'))
print("Greeter client received: " + response.message)
stub
参考:
中文示例:https://doc.oschina.net/grpc?t=60138
helloword官方示例:https://grpc.io/docs/quickstart/python/