ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JAVA和Python的GRPC远程调用

2021-06-19 23:29:55  阅读:250  来源: 互联网

标签:java JAVA proto Python server GRPC import python grpc


JAVA和Python的GRPC远程调用

1.使用springboot项目搭建Java端

1.1pom.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.grpc</groupId>
    <artifactId>server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>java_server</name>
    <description>JAVa的grpc端</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.26.0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.26.0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.26.0</version>
        </dependency>
        <!--        lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.6.2</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <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.26.0:exe:${os.detected.classifier}</pluginArtifact>
                    <!--默认值-->
                    <protoSourceRoot>${project.basedir}/src/main/resources/proto</protoSourceRoot>
                    <outputDirectory>${project.basedir}/src/main/java/com/grpc/shiyun</outputDirectory>
                    <!--设置是否在生成java文件之前清空outputDirectory的文件,默认值为true,设置为false时也会覆盖同名文件-->
                    <clearOutputDirectory>true</clearOutputDirectory>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

image-20210326195928580

1.2书写proto文件autochat.proto

syntax = "proto3";

option java_multiple_files = true;
package shiyun;

// The greeting service definition.
service AutoChat {
  // Sends a greeting
  rpc autoChat (AutoChatRequest) returns (AutoChatReply) {}
}

// The request message containing the user's name.
message AutoChatRequest {
  string question = 1;
}

// The response message containing the greetings
message AutoChatReply {
  string response = 1;
}

1.3使用protobuf插件生成Java代码

首先点击compile命令生成代码,然后再点击compile-custom生成代码,分两次生成。

image-20210326200136256

image-20210326200500587

image-20210326200538783

2.使用Python生成代码

2.1安装protobuf

pip install grpcio

2.2使用 protoc 编译 proto 文件, 生成 python 语言的实现

# 安装 python 下的 protoc 编译器
pip install grpcio-tools

2.3编写autochat.proto文件(和Java的一致)

syntax = "proto3";
#在Python时候不需要这个选项
#option java_multiple_files = true;
package shiyun;

// The greeting service definition.
service AutoChat {
  // Sends a greeting
  rpc autoChat (AutoChatRequest) returns (AutoChatReply) {}
}

// The request message containing the user's name.
message AutoChatRequest {
  string question = 1;
}

// The response message containing the greetings
message AutoChatReply {
  string response = 1;
}

image-20210326202315783

2.4编译文件

# 编译 proto 文件
python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. autochat.proto

python -m grpc_tools.protoc: python 下的 protoc 编译器通过 python 模块(module) 实现, 所以说这一步非常省心
–python_out=. : 编译生成处理 protobuf 相关的代码的路径, 这里生成到当前目录
**–grpc_python_out=. : 编译生成处理 grpc 相关的代码的路径

-I. autochat.proto : proto 文件的路径, 这里的 proto 文件在当前目录

image-20210326202330946

image-20210326202439991

3.编写Java客户端代码

package com.grpc.client;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import shiyun.AutoChatRequest;

import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

public class AutoChatClient {
    private static final Logger logger = Logger.getLogger(AutoChatClient.class.getName());

    private final ManagedChannel channel;
    private final shiyun.AutoChatGrpc.AutoChatBlockingStub blockingStub;

    /**
     * Construct client connecting to HelloWorld server at {@code host:port}.
     */
    public AutoChatClient(String host, int port) {
        this(ManagedChannelBuilder.forAddress(host, port)
                // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
                // needing certificates.
                .usePlaintext()
                .build());
    }

    /**
     * Construct client for accessing HelloWorld server using the existing channel.
     */
    AutoChatClient(ManagedChannel channel) {
        this.channel = channel;
        blockingStub = shiyun.AutoChatGrpc.newBlockingStub(channel);
    }

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

    /**
     * Say hello to server.
     */
    public void sendQuestion(String question) {
        AutoChatRequest request = shiyun.AutoChatRequest.newBuilder().setQuestion(question).build();
        shiyun.AutoChatReply response;
        try {
            response = blockingStub.autoChat(request);
            logger.info("接收来自服务器的响应: " + response.getResponse());
        } catch (StatusRuntimeException e) {
            logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
            return;
        }

    }

    /**
     * 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 {
        // Access a service running on the local machine on port 50052
        AutoChatClient client = new AutoChatClient("localhost", 50052);
        try {
            String user = "world";
            // Use the arg as the name to greet if provided
            if (args.length > 0) {
                user = args[0];
            }
            int i = 0 ;
           while (true){
               client.sendQuestion(user+i++);
               Thread.sleep(1000);
           }
        } finally {
            client.shutdown();
        }
    }
}

4.Python服务端代码

from concurrent import futures
import time
import grpc

# 实现 proto 文件中定义的 AutoChatServicer
import autochat_pb2_grpc, autochat_pb2

_ONE_DAY_IN_SECONDS = 60 * 60 * 24


class AutoChatServer(autochat_pb2_grpc.AutoChatServicer):
    def autoChat(self, request, context):
        print("接收到客户端消息:" + request.question)
        return autochat_pb2.AutoChatReply(response= request.question)


def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    autochat_pb2_grpc.add_AutoChatServicer_to_server(AutoChatServer(), server)
    server.add_insecure_port('[::]:50052')
    print("启动服务器等待连接。。。。")
    server.start()
    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        server.stop(0)


if __name__ == '__main__':
    serve()

5.项目源代码已经同步到GitHub和gitee,如有需要请移步自行下载:

gitee: https://gitee.com/ljf2402901363/grpc.git

github: https://github.com/LJF2402901363/grpc.git

6.本博客已同步到个人博客,如有需要请移步:

http://moyisuiying.com/index.php/javastudy/springboot/479.html

标签:java,JAVA,proto,Python,server,GRPC,import,python,grpc
来源: https://blog.csdn.net/u011870022/article/details/118060375

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有