Grpc python 客户端服务器流式传输未按预期工作
Grpc python client server streaming not working as expected
一个简单的 grpc 服务器客户端,客户端发送一个 int,服务器返回 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()
原型文件:
语法 = "proto3";
service Test {
rpc Produce (Rq) returns (stream Rs);
}
message Rq{
int32 val = 1;
}
message Rs{
int32 st = 1;
}
启动服务器后
当我 运行 客户端时,服务器端生成器启动 运行ning 并立即完成它循环范围。
我所期望的是它会随着客户的电话一个接一个地出现,但事实并非如此。
这是预期的行为吗?我的客户端仍在打印值,但服务器已经完成了该功能。
是的,这种行为是预期的。 gRPC 的特点是在 RPC 的两侧之间进行流量控制(这样在一侧生成消息的速度太快不会耗尽另一侧的内存),但也有少量缓冲的余地(因此相当少量的数据可以在另一方明确要求之前由一方发送)。在您的情况下,从服务器发送到客户端的二十条消息都在这个小限额之内。服务端 gRPC Python 运行时正在调用您的服务端 Produce
方法,消耗其全部输出的 20 条消息,并通过网络将所有这些消息发送到您的客户端,它们在本地由调用端 gRPC Python 运行时,直到你的调用端 test
函数要求它们。
如果您想查看流量控制的效果,请尝试使用大消息(大小为 1 兆字节左右)或更改允许量的大小(我认为这是通过通道参数完成的,但那些是一项高级且相对不受支持的功能,因此将其留作练习)。
一个简单的 grpc 服务器客户端,客户端发送一个 int,服务器返回 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()
原型文件: 语法 = "proto3";
service Test {
rpc Produce (Rq) returns (stream Rs);
}
message Rq{
int32 val = 1;
}
message Rs{
int32 st = 1;
}
启动服务器后 当我 运行 客户端时,服务器端生成器启动 运行ning 并立即完成它循环范围。 我所期望的是它会随着客户的电话一个接一个地出现,但事实并非如此。 这是预期的行为吗?我的客户端仍在打印值,但服务器已经完成了该功能。
是的,这种行为是预期的。 gRPC 的特点是在 RPC 的两侧之间进行流量控制(这样在一侧生成消息的速度太快不会耗尽另一侧的内存),但也有少量缓冲的余地(因此相当少量的数据可以在另一方明确要求之前由一方发送)。在您的情况下,从服务器发送到客户端的二十条消息都在这个小限额之内。服务端 gRPC Python 运行时正在调用您的服务端 Produce
方法,消耗其全部输出的 20 条消息,并通过网络将所有这些消息发送到您的客户端,它们在本地由调用端 gRPC Python 运行时,直到你的调用端 test
函数要求它们。
如果您想查看流量控制的效果,请尝试使用大消息(大小为 1 兆字节左右)或更改允许量的大小(我认为这是通过通道参数完成的,但那些是一项高级且相对不受支持的功能,因此将其留作练习)。