如何使用 Python 为 Java 编写的 gRPC 服务编写 gRPC 客户端

Ezi*_*zio 1 python java grpc grpc-java grpc-python

我无法带着这种困惑继续前进,因为我不知道该怎么办。Python 中的大多数教程都会获取定义方法的主类名称,但当您只需要编写客户端时,不知道如何执行此操作。

And*_*ong 8

我怀疑您是初学者或中级程序员,因此如果您负责或尝试编写自己的gRPC客户端这样复杂的事情,我会感到非常惊讶。我的猜测是,您实际上只想从 Java gRPC 服务读取数据,并且您已经阅读了有关使用 Python gRPC 客户端的信息,但您对如何执行此操作感到困惑。

客户端的简化示例。

首先,我们来谈谈客户端如何工作。想象一下编写一个像这样的Python类

class MyClient:
    def __init__(self, address, port):
        self.address = address
        self.port = port
        // create a grpc channel

    def connect(self):
        // connect the channel

    def read(self):
        // read the channel
Run Code Online (Sandbox Code Playgroud)

然后在您的主函数中,您将创建此客户端的实例,使用它来连接和读取(或写入)消息。因此,客户端只是一个对象,它负责连接到某个地方并为您读取消息等脏活。

上面是一个很糟糕的例子,因为这并不是 gRPC 真正的工作原理。我只是认为更传统的连接和读取示例会更容易理解。现在您可以看到主函数和通用客户端之间的连接。

那么,gRPC 如何适应这一点呢?

gRPC 背后的整个想法是您不必编写客户端。按如下步骤查看:

  1. 有人首先编写了一个 .proto 文件来“定义”他们的服务。他们定义了该服务将具有哪些类型的端点,例如 getThings()doThat()

  2. 然后他们使用程序或插件 (grpc-java) 生成一个基本完成的 Java 应用程序。未完成的部分是:到底是什么getThings()doThat()做什么。

  3. 他们填写了该代码……然后就完成了。grpc-java 为他们生成了整个服务器代码,因此他们的服务已经启动并运行。

  4. 现在想从该服务中读取数据,但使用的是 Python。

  5. 只需获取用于生成 Java 服务的同一个 .proto 文件,然后按照以下步骤生成客户端。所以您会看到,正如他们使用程序生成大部分 Java 服务一样,您也将使用程序生成该服务的客户端。(甚至不是“大多数”。它生成一个功能齐全的客户端。)

    python -m grpc_tools.protoc --python_out=. --grpc_python_out=. your_java_service_proto_file.proto
    
    Run Code Online (Sandbox Code Playgroud)
  6. 在您的 main 函数中,您只需创建所生成客户端的实例(指定 Java 服务的 IP 地址和端口),然后就可以开始了:

    channel = grpc.insecure_channel('10.123.123.123:54321')
    stub = the_generated_thing.RouteGuideStub(channel)
    things_from_java_service = stub.getThings()
    
    Run Code Online (Sandbox Code Playgroud)

总结和另一种看待它的方式

将 gRPC 视为由https://grpc.io/编写的一套程序,可以为每个人生成代码。

有人在 .proto 文件中定义了一项服务,然后使用其中一个 gRPC 程序(在您的例子中为 grpc-java)来生成服务器的大部分内容。然后他们实施了其余部分并部署了该服务器。

现在,像您这样的任何人都可以通过另一个gRPC 程序(在您的例子中为 grpc-python)提供相同的 .proto 文件,以您选择的语言生成功能齐全的客户端。您可以在主函数中加载生成的客户端,然后就可以与另一端的服务器进行交互。