【gRPC】Python调用Java的gRPC服务

2020 年 04 月 22 日 阅读数: 11
【gRPC】Python调用Java的gRPC服务

本文旨在用 Java 搭建一个非常简单的 say hello gRPC 服务,并用 Python 语言调用。

gRPC介绍

.proto 文件

首先定一个非常简单的 hello.proto 文件来定义 gRPC 接口以及参数对象。

syntax = "proto3";
option java_package = "com.github.jwenjian.example.grpc";
option java.multiple_files = true;
package com.github.jwenjian.example.grpc;
service HelloService {
rpc sayHello(HelloRequest) returns (HelloResponse) {}
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string msg = 1;
}

上面的 hello.proto 文件定义了一个 HelloService 的服务,里面定义了一个 rpc 方法 sayHello, 方法的参数是 HelloRequest 类型,返回值是 HelloResponse 类型。

HelloRequest, HelloResponse的定义非常简单,都只有一个 string 类型的字段。

服务端

Java 代码生成

  1. 在项目中新建 src/main/proto 文件夹,将上面的 hello.proto 放进去。

  2. 在 Maven 工程中,配置 pom.xml 添加以下依赖和打包配置:

<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.28.0</version>
</dependency>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.11.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.28.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
  1. 在项目根目录执行 mvn compile 即可生成和 proto 文件对应的 java 代码。

生成的代码在 target/generated-resources/protobuf/grpc-java 和 target/generated-resources/protobuf/java 两个文件夹下,一个用来存放 HelloService 相关代码,另一个用来存放 HelloRequest,HelloResponse 相关代码。

接口实现

新建一个java文件,HelloServiceImpl.java, 继承上一步自动生成的service代码中的抽象实现类,并重写 sayHello 方法即可:

public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
@Override
public void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
System.out.println("hello request, name = " + request.getName());
HelloResponse response = HelloResponse.newBuilder().setMsg("hello, " + request.getName()).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}

代码足够简单,不再多做说明。

启动 gRPC 服务

在入口类的 main 方法中创建 Server 对象,监听端口,添加刚才的 service 实现类后启动。

public static void main(String[] args) {
Server server = ServerBuilder.forPort(8003)
.addService(new HelloServiceImpl())
.build()
.start();
System.out.println("gRPC server started on port 8003");
server.awaitTermination();
}

运行 main 方法之后,我们就有了一个 gRPC 服务运行在 localhost:8003.

客户端

客户端代码生成

  1. 将 hello.proto 文件放在 python 工程根目录下的 proto 文件夹下。

  2. 安装依赖

pip install grpcio grpcio-tools
  1. 代码生成

python -m grpc_tools.protoc -I ./proto --python_out=. --grpc_python_out=. ./proto/hello.proto

其中:

  • -I 指定 .proto 文件所在的文件夹

  • python_out 指定 HelloRequest, HelloResponse 等 message 对象编译出来的python文件存放目录

  • grpc_python_out 指定 HelloService 相关的 python 文件存放目录

如果本地安装的是 Python 3, 把上面的命令改成相应的 pip3 和 python3

调用 gRPC 服务

在 client.py 中引入生成的代码,设置刚才启动的 gRPC 服务的地址,调用 sayHello 方法。

import grpc
import hello_pb2_grpc
import hello_pb2
channel = grpc.insecure_channel("localhost:8003")
stub = hello_pb2_grp.HelloServiceStub(channel)
resp: hello_pb2.HelloResponse = stub.sayHello(hello_pb2.HelloRequest(name = "world"))
print("resp msg = {0}".format(resp.msg))

运行 client.py 即可在客户端看到返回结果:

resp msg = hello, world

文中示例代码在 Github 上可找到。

用户头像

遇见

关注

A good code is like a story not a puzzle 2019.08.08 加入

人生是 B 和 D 之间的 C 选择。

评论

发布
暂无评论
【gRPC】Python调用Java的gRPC服务