springboot实现 grpc any服务器端 springboot整合grpc_grpc

 

这个是运行的结果图片左侧是grpc的服务端,右侧是调用grpc的客户端,我的代码是拆成了两个SpringBoot项目,这样可能会方便大家理解。

Server主要代码

第一步、pom文件:这里要说明一下,不同版本的proto配置文件都是不同的,如果想直接启动就用的话,建议用我的代码直接跑

<?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.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo4</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo4</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <grpc.version>1.36.0</grpc.version>
        <os.plugin.version>1.5.0.Final</os.plugin.version>
        <protobuf.plugin.version>0.5.0</protobuf.plugin.version>
        <protoc.version>3.3.0</protoc.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- grpc 这里的版本很重要,不同的版本代码都会有不同 -->
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
            <version>2.7.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>${grpc.version}</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>${grpc.version}</version>
        </dependency>

    </dependencies>
    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>${os.plugin.version}</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>${protobuf.plugin.version}</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

第二步、proto文件,需要创建和java/resources平级的proto文件夹,在文件夹内创建自己的proto文件(grpc是可以跨语言调用的,只要proto文件相同)

//版本
syntax = "proto3";

option java_multiple_files = true;
// grpc插件生成的类的报名,随便写
option java_package = "com.axin.test.grpc";

// grpc的方法
service TestGrpcService {
  rpc testMethod (TestRequest) returns (TestReply){}
}

// 入参对象
message TestRequest {
  string id=1;
  string name=2;
}
// 出参对象
message TestReply {
  string res=1;
}

第三步、要提供什么样的远程服务,也就是proto中定义的方法的实现,我这里叫TestGrpcService,会报错,按照图片中的三步顺序点击鼠标即可

package com.example.demo4.grpcservice;

import com.axin.test.grpc.TestGrpcServiceGrpc;
import com.axin.test.grpc.TestReply;
import com.axin.test.grpc.TestRequest;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;

/**
 * @Author axin
 **/

// 旧版本的注解需要制定类名,写法为@GrpcService(DeviceFixServiceGrpc.class)
@GrpcService
public class TestGrpcService extends TestGrpcServiceGrpc.TestGrpcServiceImplBase {

    // 重写proto中的方法
    @Override
    public void testMethod(TestRequest request, StreamObserver<TestReply> responseObserver) {
        // grpc服务端获取调用端请求参数
        String id = request.getId();
        String name = request.getName();
        // 这里可以有自己的业务代码,只需要按照porto中的返回类型返回参数即可
        TestReply res = TestReply.newBuilder().setRes("id:"+id+",name:"+name).build();
        responseObserver.onNext(res);
        responseObserver.onCompleted();
    }

}

springboot实现 grpc any服务器端 springboot整合grpc_grpc_02

第四步、在properties文件中配置grpc的端口

springboot实现 grpc any服务器端 springboot整合grpc_grpc_03

以上,服务端启动即可!!!

Client端主要代码

第一步、pom文件,这里跟服务端有点区别,还是要注意一点,不同版本的配置文件,代码都有很大的区别

<?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.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo5</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo5</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <grpc.version>1.36.0</grpc.version>
        <os.plugin.version>1.5.0.Final</os.plugin.version>
        <protobuf.plugin.version>0.5.0</protobuf.plugin.version>
        <protoc.version>3.3.0</protoc.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- grpc 这里的版本很重要,不同的版本代码都会有不同 -->
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
            <version>2.7.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>${grpc.version}</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>${grpc.version}</version>
        </dependency>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-client-spring-boot-autoconfigure</artifactId>
            <version>2.7.0.RELEASE</version>
        </dependency>

    </dependencies>
    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>${os.plugin.version}</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>${protobuf.plugin.version}</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

第二步、proto文件,需要创建和java/resources平级的proto文件夹,把Server端的粘过来直接用

第三步、创建一个service来调用server端的服务,我的叫TestService,代码同样会报错,按照Server端的第三步中的图片,分别点击Lifecycle中的clean、Plugins下的protobuf中的protobuf:compile、Plugins下的protobuf中的protobuf:compile-custom即可

package com.example.demo5.service;

import com.axin.test.grpc.TestGrpcServiceGrpc;
import com.axin.test.grpc.TestReply;
import com.axin.test.grpc.TestRequest;
import io.grpc.Channel;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;


/**
 * @Author axin
 **/
@Service
public class TestService {

    /**
     * 这里不同的版本写法也是不同,低版本得到的是channel,再去获取ServiceStub
     * 这里的stub有三种
     * ServiceBlockingStub、GrpcServiceFutureStub、GrpcServiceStub
     * 对应的是了3种Contract:
     *  BlockingStub,阻塞式
     *  FutureStub,guava的ListenableFuture
     *  Stub,支持StreamObserver
     */

    @GrpcClient("grpc-servera")
    TestGrpcServiceGrpc.TestGrpcServiceBlockingStub stub;

    public String test(){
        TestRequest request = TestRequest.newBuilder().setId("aaa").setName("bbb").build();
        TestReply reply = stub.testMethod(request);
        return "那边的结果"+reply.getRes();
    }
}

第四步、配置写好

server.port=8082

#这里的不同版本写法也是不同,低版本写法如下
#grpc.client.grpc-servera.host=127.0.0.1
#grpc.client.grpc-servera.port=30081
#新版本写法,这里的grpc-servera是什么,service中的注解值就是什么
grpc.client.grpc-servera.address=static://127.0.0.1:30081
grpc.client.grpc-servera.negotiationType=plaintext

springboot实现 grpc any服务器端 springboot整合grpc_grpc_04

第五步、弄个controller测试一下

springboot实现 grpc any服务器端 springboot整合grpc_maven_05

 

以上,就是全部了,原理建议自己在后续的开发中自己摸索,这样记得深记得牢。

代码下载:

链接: https://pan.baidu.com/s/1f-RSTEmKJNaEU36g1hbwqw 提取码: dq77 

链接: https://pan.baidu.com/s/1SlBBAHyWItNQTNN9LFGyZg 提取码: 6u8h