Search code examples
protocol-buffersgrpc

How do I represent a two-dimensional array in Protocol Buffers?


for example:

[[1,2],[3,4]...]

I just wanted to test if RPC supported a two-dimensional array, But there is something wrong, I am following the official docs.

The server is as follows:

data = [[i, 9] for i in range(128)]


class Greeter(hello_pb2_grpc.GreeterServicer):

    def SayHello(self, request, context):
        return hello_pb2.HelloReply(results=data)


def serve():

    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), options=[
                     (cygrpc.ChannelArgKey.max_send_message_length, -1),
                     (cygrpc.ChannelArgKey.max_receive_message_length, -1)
      ])
    hello_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port('[::]:50052')
    server.start()
    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        server.stop(0)

if __name__ == '__main__':
    serve()

The client is as follows:

def insecure_channel(host, port):
        channel = grpc.insecure_channel(
            target=host if port is None else '%s:%d' % (host, port),
            options=[(cygrpc.ChannelArgKey.max_send_message_length, -1),
                     (cygrpc.ChannelArgKey.max_receive_message_length, -1)])
        return grpc.beta.implementations.Channel(channel)

def run():
    channel = grpc.insecure_channel('localhost:50052')
    stub = hello_pb2_grpc.GreeterStub(channel)
    st = time.time()
    response = stub.SayHello(hello_pb2.HelloRequest(name='test'))
    et = time.time() - st
    print("Greeter client received: {}, {}".format(type(response.results), et))


if __name__ == '__main__':
    run()

The protobuf definition is as follows:

syntax = "proto3";

package hello;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
    repeated Result results = 1;
}

message Result {
    repeated int32 index = 1;
    repeated int32 count = 2;
}

But I get the error like this:

  File "greeter_server.py", line 19, in SayHello
    return hello_pb2.HelloReply(results=data)
TypeError: Parameter to MergeFrom() must be instance of same class: expected hello.Result got list.

I am using python3.

Thanks in advance.


Solution

  • As per your question, [[1,2],[3,4]...] is an array of arrays.

    Something like this should solve your problem:

    message InternalArray {
        repeated int internal_array = 1;
    }
    repeated InternalArray array = 1;