spring整合grpc

添加依赖

 <properties>
        <java.version>1.8</java.version>
        <grpc.version>1.6.1</grpc.version>
        <protobuf.version>3.3.0</protobuf.version>
    </properties>
    <!-- google.protobuf -->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.5.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.api.grpc</groupId>
            <artifactId>proto-google-common-protos</artifactId>
            <version>1.12.0</version>
        </dependency>

        <dependency>
            <groupId>com.googlecode.protobuf-java-format</groupId>
            <artifactId>protobuf-java-format</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
            <version>1.17.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <version>3.5.0</version>
        </dependency>

        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-client-spring-boot-starter</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>23.6-jre</version>
        </dependency>


配置插件

在项目的pom.xml中加入相关插件的配置内容,可以直接复制grpc官方的

<build>
  <extensions>
    <extension>
      <groupId>kr.motd.maven</groupId>
      <artifactId>os-maven-plugin</artifactId>
      <version>1.4.1.Final</version>
    </extension>
  </extensions>
  <plugins>
    <plugin>
      <groupId>org.xolstice.maven.plugins</groupId>
      <artifactId>protobuf-maven-plugin</artifactId>
      <version>0.5.0</version>
      <configuration>
        <protocArtifact>com.google.protobuf:protoc:3.3.0:exe:${os.detected.classifier}</protocArtifact>
        <pluginId>grpc-java</pluginId>
        <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.4.0:exe:${os.detected.classifier}</pluginArtifact>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>compile</goal>
            <goal>compile-custom</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins><build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.4.1.Final</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.5.0</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>
                    <!--默认值-->
                    <protoSourceRoot>${project.basedir}/src/main/resources</protoSourceRoot>
                    <!--默认值-->
                    <!--<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>-->
                    <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
                    <!--设置是否在生成java文件之前清空outputDirectory的文件,默认值为true,设置为false时也会覆盖同名文件-->
                    <clearOutputDirectory>false</clearOutputDirectory>
                    <!--更多配置信息可以查看https://www.xolstice.org/protobuf-maven-plugin/compile-mojo.html-->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</build>

生成文件

在IDE的maven面板上分别点击下面两个任务。点击protobuf:compile生成的5个文件是与protobuf序列化相关的,也就相当于是数据交换时的java bean。点击protobuf:compile-custom生成的1个文件是与grpc相关的,主要用于与服务端通信的。

grpc服务端

@Slf4j
@GrpcService()
public class DeviceGrpcService extends DeviceFixServiceGrpc.DeviceFixServiceImplBase {

    @Override
    public void insertDeviceFix(deviceFix request, StreamObserver<booleanReply> responseObserver) {

        // 返回体构建,入参在request中,这边省略业务代码
        booleanReply reply = booleanReply.newBuilder().build();
        // 返回参数
        responseObserver.onNext(reply);
        responseObserver.onCompleted();

    }
}

继承生成对象,具体实现其中定义好的方法,即双方在文件中约定好的参数以及接口。
定义grpc服务端接口。

grpc:
  server:
      port: 9090

grpc客户端

public class DeviceGrpcClient {
    /**
     * 阻塞模式
     * 拦截器需要在注解里写明
     */
    @GrpcClient(value = "myservice", interceptors = HeaderClientInterceptor.class)
    DeviceFixServiceGrpc.DeviceFixServiceBlockingStub deviceFixServiceBlockingStub;

    /**
     * 其中定义好的一个接口
     *
     * @param request
     * @return
     */
    public booleanReply insertDeviceFix(deviceFix request) {
        // 业务代码
        return deviceFixServiceBlockingStub.insertDeviceFix(request);
    }
}

客户端可以实现自定义拦截器,在数据抵达channel之前对数据拦截做一些相关操作,服务端也可以实现相应拦截器,双方做一些数据的交互。

@GrpcGlobalClientInterceptor
@Slf4j
public class HeaderClientInterceptor implements ClientInterceptor {


    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
                                                               CallOptions callOptions,
                                                               Channel next) {
        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(
                next.newCall(method, callOptions)) {

            @Override
            public void start(Listener<RespT> responseListener, Metadata headers) {


                // 这边可以将自己需要的请求头传入,双方做好约定校验
                super.start(
                        new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(
                                responseListener) {
                            @Override
                            public void onHeaders(Metadata headers) {
                                super.onHeaders(headers);

                            }
                        }, headers);
            }
        };
    }
}

配置文件

  client:
    myservice:
      # 传输类型,默认是ssl
      negotiationType: PLAINTEXT
      address: static://127.0.0.1:5012

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×