Python grpc - 在发送响应之前读取所有消息

发布于 2025-01-12 02:07:48 字数 1879 浏览 0 评论 0原文

我试图了解使用流的 grpc 服务器是否能够在发送响应之前等待读取所有客户端消息。

我有一个简单的应用程序,我在其中发送了几个我想要添加和返回的号码。 我已经设置了一个基本的原型文件来测试这一点:

syntax = "proto3";


message CalculateRequest{
    int64 x = 1;
    int64 y = 2;
};

message CalculateReply{
    int64 result = 1;
}

service Svc {
    rpc CalculateStream (stream CalculateRequest) returns (stream CalculateReply);
}

在我的服务器端,我已经实现了以下代码,该代码在收到消息时返回答案消息:

class CalculatorServicer(contracts_pb2_grpc.SvcServicer):
    def CalculateStream(self, request_iterator, context):
        for request in request_iterator:
            resultToOutput = request.x + request.y
            yield contracts_pb2.CalculateReply(result=resultToOutput)

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    contracts_pb2_grpc.add_SvcServicer_to_server(
        CalculatorServicer(), server)
    server.add_insecure_port('localhost:9000')
    server.start()
    server.wait_for_termination()


if __name__ == '__main__':
    print( "We're up")
    logging.basicConfig()
    serve()

我想对此进行调整以首先读取所有数字并然后在稍后阶段发送这些内容 - 如下所示:

class CalculatorServicer(contracts_pb2_grpc.SvcServicer):
   listToReturn = []
   def CalculateStream(self, request_iterator, context):
        for request in request_iterator:
            listToReturn.append (request.x + request.y)
        
        # ...
        # do some other stuff first before returning
        
        for item in listToReturn:
           yield contracts_pb2.CalculateReply(result=resultToOutput)

目前,我稍后写出的实现不起作用,因为从未到达底部的代码。这是设计使连接在到达那里之前似乎“关闭”吗?

grpc.io 网站表明这应该可以通过 BiDirectional 实现流媒体:

例如,服务器可以在写入响应之前等待接收所有客户端消息,或者它可以交替读取消息然后写入消息,或者其他读取和写入的组合。

预先感谢您的任何帮助:)

I'm trying to understand if grpc server using streams is able to wait for all client messages to be read in prior to sending responses.

I have a trivial application where I send in several numbers I'd like to add and return.
I've set up a basic proto file to test this:

syntax = "proto3";


message CalculateRequest{
    int64 x = 1;
    int64 y = 2;
};

message CalculateReply{
    int64 result = 1;
}

service Svc {
    rpc CalculateStream (stream CalculateRequest) returns (stream CalculateReply);
}

On my server-side I have implemented the following code which returns the answer message as the message is received:

class CalculatorServicer(contracts_pb2_grpc.SvcServicer):
    def CalculateStream(self, request_iterator, context):
        for request in request_iterator:
            resultToOutput = request.x + request.y
            yield contracts_pb2.CalculateReply(result=resultToOutput)

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    contracts_pb2_grpc.add_SvcServicer_to_server(
        CalculatorServicer(), server)
    server.add_insecure_port('localhost:9000')
    server.start()
    server.wait_for_termination()


if __name__ == '__main__':
    print( "We're up")
    logging.basicConfig()
    serve()

I'd like to tweak this to first read in all the numbers and then send these out at a later stage - something like the following:

class CalculatorServicer(contracts_pb2_grpc.SvcServicer):
   listToReturn = []
   def CalculateStream(self, request_iterator, context):
        for request in request_iterator:
            listToReturn.append (request.x + request.y)
        
        # ...
        # do some other stuff first before returning
        
        for item in listToReturn:
           yield contracts_pb2.CalculateReply(result=resultToOutput)

Currently, my implementation to write out later doesn't work as the code at the bottom is never reached. Is this by design that the connection seems to "close" before reaching there?

The grpc.io website suggests that this should be possible with BiDirectional streaming:

for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes.

Thanks in advance for any help :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瑕疵 2025-01-19 02:07:48

这里的问题是“所有客户端消息”的定义。在传输级别,服务器无法知道客户端是否已完成,而与客户端关闭其连接无关。

您需要添加一些指示,表明客户端已完成向协议发送请求。向现有的CalculateRequest 添加一个bool 字段,或者添加一个顶级oneof,其中一个选项类似于StopSendingRequests

The issue here is the definition of "all client messages." At the transport level, the server has no way of knowing whether the client has finished independent of the client closing its connection.

You need to add some indication of the client's having finished sending requests to the protocol. Either add a bool field to the existing CalculateRequest or add a top-level oneof with one of the options being something like a StopSendingRequests

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文