Grpc python客户端服务器流不能按预期工作

时间:2017-10-31 21:47:37

标签: python python-3.x grpc

一个简单的grpc服务器客户端,客户端发送int和服务器流回来。

客户端逐个读取消息,但服务器立即为所有响应运行生成器函数。

服务器代码:

import test_pb2_grpc as pb_grpc
import test_pb2 as pb2
import time
import grpc
from concurrent import futures

class test_servcie(pb_grpc.TestServicer):

    def Produce(self, request, context):
        for i in range(request.val):
            print("request came")
            rs = pb2.Rs()
            rs.st = i + 1
            yield rs



    def serve():


        server = 
        grpc.server(futures.ThreadPoolExecutor(max_workers=10))
        pb_grpc.add_TestServicer_to_server(test_servcie(), server)
        server.add_insecure_port('[::]:50051')
        print("service started")
        server.start()
        try:
            while True:
                time.sleep(3600)
        except KeyboardInterrupt:
            server.stop(0)


if __name__ == '__main__':
    serve()

客户代码:

import grpc
import test_pb2_grpc as pb_grpc
import test_pb2 as pb
def test():
    channel = grpc.insecure_channel(
    '{host}:{port}'.format(host="localhost", port=50051))

    stub = pb_grpc.TestStub(channel=channel)

    req = pb.Rq()
    req.val = 20
    for s in stub.Produce(req):
        print(s.st)
        import time
        time.sleep(10)

test()

原型文件:     syntax =" proto3&#34 ;;

service Test {
    rpc Produce (Rq) returns (stream Rs);
}

message Rq{
    int32 val = 1;
}
message Rs{
    int32 st = 1;
}
启动服务器后

当我运行客户端时,服务器端生成器开始运行并立即完成它循环范围。 我所期望的是它会一个接一个地作为客户来电,但事实并非如此。 这是一种预期的行为。我的客户端仍在打印值,但服务器已经完成了该功能。

1 个答案:

答案 0 :(得分:3)

是的,这种行为是预料之中的。 gRPC具有RPC两侧之间的流量控制(因此在一侧产生过快的消息不会耗尽另一侧的内存)但是也允许少量缓冲(因此相当少量的数据可以在另一方明确要求之前由一方发送。在您的情况下,从服务器发送到客户端的20条消息都符合这个小额限。服务端gRPC Python运行时调用服务端Produce方法,消耗其全部输出的20条消息,并将所有这些消息通过网络发送到客户端,在那里它们由调用端本地保存gRPC Python运行时,直到你的调用端test函数要求它们。

如果你想看到流量控制的效果,请尝试使用大量的消息(大小为1兆字节)或改变容差的大小(我认为这是通过通道参数完成的,但这些是高级的和相对不支持的功能,所以这是一个练习)。