python与java使用grpc以及java作为客户端调用python服务的小demo

python使用grpc

  1. 使用的工具:python3.8 pycharm2020.2

  2. 安装环境:

     python -m pip install grpcio
     python -m pip install grpcio-tools
     python -m pip install protobuf
    

    python与java使用grpc以及java作为客户端调用python服务的小demo_第1张图片

  3. 建立一个python项目,创建以下文件
    python与java使用grpc以及java作为客户端调用python服务的小demo_第2张图片

  4. 写下helloworld.proto,进行编译

    helloworld.proto

    
    syntax = "proto3";
    
    option java_package = "com.grpc.test";
    
    package helloworld;
    
    
    service Greeter {
      // Sends a greeting
      rpc SayHello (HelloRequest) returns (HelloReply) {}
    }
    
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings
    message HelloReply {
      string message = 1;
    }
    

    输入命令对helloworld.proto进行编译,生成了helloworld_pb2.py和helloworld_pb2_grpc.py

     python -m grpc_tools.protoc -I=. --python_out=. -- grpc_python_out=. helloworld.proto
    
  5. 写入service.py和client.py

    service.py

    import time
    from concurrent import futures
    
    import grpc
    
    import helloworld_pb2
    import helloworld_pb2_grpc
    
    _ONE_DAY_IN_SERVICE = 60 * 60 * 24
    IP = "[::]:50051"
    
    
    class service(helloworld_pb2_grpc.GreeterServicer):
    
        def SayHello(self, request, context):
            txt = request.name
            return helloworld_pb2.HelloReply(message='hello2 {msg}'.format(msg=txt))
    
    
    def serve():
        grpcServer = grpc.server(futures.ThreadPoolExecutor(max_workers=4))
        helloworld_pb2_grpc.add_GreeterServicer_to_server(service(), grpcServer)
        grpcServer.add_insecure_port(IP)
        grpcServer.start()
        print("server start success")
    
        try:
            while True:
                time.sleep(_ONE_DAY_IN_SERVICE)
        except KeyboardInterrupt:
            grpcServer.stop(0)
    
    
    if __name__ == '__main__':
        serve()
    

    client.py

    import grpc
    import helloworld_pb2
    import helloworld_pb2_grpc
    
    IP = 'localhost:50051'
    
    
    def run():
        channel = grpc.insecure_channel(IP)
        stub = helloworld_pb2_grpc.GreeterStub(channel=channel)
        response = stub.SayHello(helloworld_pb2.HelloRequest(name='luo'))
        print("recevied: " + response.message)
    
    
    if __name__ == '__main__':
        run()
    

6.先运行service.py,再运行client.py,客户端和服务器端通过端口50051成功通信
python与java使用grpc以及java作为客户端调用python服务的小demo_第3张图片
python与java使用grpc以及java作为客户端调用python服务的小demo_第4张图片

java中使用grpc

  1. 使用的工具:java 1.8.0 idea

  2. 首先建立一个maven工程,并在maven工程下src/main目录下建立proto文件夹(这个proto文件夹只能在这里建立,是为了下面更好的编译,减少不必要的麻烦),具体目录如下:

    python与java使用grpc以及java作为客户端调用python服务的小demo_第5张图片

  3. 写入helloworld.proto文件,这个文件与python中使用的要是同一个

  4. 修改pom.xml,引入依赖和插件

 <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.16.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.16.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.16.1</version>
        </dependency>
    </dependencies>
    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.5.0.Final</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.16.1:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
  1. 在idea的终端输入 mvn compile,会在target目录下生成如下文件:GreeterGrpc.java和Helloworld.java
    python与java使用grpc以及java作为客户端调用python服务的小demo_第6张图片
  2. 将上面的文件剪切到如下目录(目录是根据proto文件新建的)
    python与java使用grpc以及java作为客户端调用python服务的小demo_第7张图片
  3. 再创建一个服务端处理消息的类SayHelloImpl,实现我们服务定义的生成的服务接口,做我们的服务的实际的“工作”。
package com.grpc.test;

import io.grpc.stub.StreamObserver;

/**
 * @author luoaojin
 * @CreateTime 2018-11-14
 * @Description
 */
public class SayHelloImpl extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(Helloworld.HelloRequest request, StreamObserver<Helloworld.HelloReply> responseObserver) {
//     这一行一定要删除,否则会提示你没有实现这个方法。
//        super.sayHello(request, responseObserver);
        System.out.println(request.getName());

        Helloworld.HelloReply data = Helloworld.HelloReply.newBuilder().setMessage("Hello " + request.getName()).build();

        responseObserver.onNext(data);
        responseObserver.onCompleted();
    }

}
  1. 编写客户端Client.java和服务端DefinedServer.java
    Client.java
package com.grpc.test;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;

import java.util.concurrent.TimeUnit;

/**
 * @author luoaojin
 * @CreateTime 2018-11-14
 * @Description
 */
public class Client {

    private final ManagedChannel channel;
    private final GreeterGrpc.GreeterBlockingStub blockingStub;

    /**
     * Construct client connecting to HelloWorld server at {@code host:port}.
     */
    public Client(String host, int port) {

        channel = ManagedChannelBuilder.forAddress(host, port)
                .usePlaintext()
                .build();
        blockingStub = GreeterGrpc.newBlockingStub(channel);
    }

    public void shutdown() throws InterruptedException {
        channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
    }

    /**
     * Say hello to server.
     */
    public void greet(String name) {

        Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build();
        Helloworld.HelloReply response;
        try {
            response = blockingStub.sayHello(request);
        } catch (StatusRuntimeException e) {
            System.out.println("RPC failed: {0}"+ e.getStatus());
            return;
        }
        System.out.println(("Greeting: " + response.getMessage()));
    }

    /**
     * Greet server. If provided, the first element of {@code args} is the name to use in the
     * greeting.
     */
    public static void main(String[] args) throws Exception {
        Client client = new Client("localhost", 50051);
        try {

            String user = "luo";
            if (args.length > 0) {
                user = args[0];
            }
            client.greet(user);
        } finally {
            client.shutdown();
        }
    }

}

DefinedServer

package com.grpc.test;

import io.grpc.Server;
import io.grpc.ServerBuilder;


import java.io.IOException;

/**
 * @author luoaojin
 * @CreateTime 2018-11-14
 * @Description
 */
public class DefinedServer {

    private Server server;

    private void start() throws IOException {
        server = ServerBuilder.forPort(50051)//服务端只用指定端口号
                .addService(new SayHelloImpl())
                .build()
                .start();

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                // Use stderr here since the logger may have been reset by its JVM shutdown hook.
                System.err.println("*** shutting down gRPC server since JVM is shutting down");
                this.stop();
                System.err.println("*** server shut down");
            }
        });
    }

    private void stop() {
        if (server != null) {
            server.shutdown();
        }
    }

    /**
     * Await termination on the main thread since the grpc library uses daemon threads.
     */
    private void blockUntilShutdown() throws InterruptedException {
        if (server != null) {
            server.awaitTermination();
        }
    }

    /**
     * Main launches the server from the command line.
     */
    public static void main(String[] args) throws IOException, InterruptedException {
        final DefinedServer server = new DefinedServer();
        server.start();
        server.blockUntilShutdown();
    }


}


  1. 先运行服务器端,再运行客户端,客户端和服务器端通过端口50051成功通信(注意端口占用问题)
    python与java使用grpc以及java作为客户端调用python服务的小demo_第8张图片

java客户端调用python服务端

运行java的客户端和python的服务端即可,二者即可通信

你可能感兴趣的:(java,web,python,java)