第一个gRPC程序的开发

81 阅读2分钟

参考up:孙哥
孙哥主页

项目结构

xxx-api  模块
  定义 protobuf idl语言
  并且通过命令创建具体的代码,后续client  server引入使用
  1. message
  2. service

xxx-server模块
  1.实现api模块中定义的服务接口
  2. 发布gRPC服务(创建服务端程序)

xxx-client模块
  1. 创建服务端stub(代理)
  2. 基于代理  RPC调用

grpr-api开发

编写proto文件

option java_package="com.suns";

option java_outer_classname="HelloProto";

/*
      IDL文件  目的  发布RPC服务  service---->message            message<-----
*/

message HelloRequest{
  string name=1;
}
message  HelloResponse{
  string result=1;
}

service HelloServer{
  rpc hello(HelloRequest) returns (HelloResponse){}
}

通过 protoc命令 把proto文件的IDL 转换成编程语言

protoc --java_out=/xxx/xxx /xxx/xxx/xx.proto 命令 生成java代码 生成位置 proto文件

实战中 使用 maven插件 进行protobuf IDL 文件的编译,把他放在IDEA具体问题

引入依赖

    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.52.1</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.52.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.52.1</version>
        </dependency>
        <dependency> <!-- necessary for Java 9+ -->
            <groupId>org.apache.tomcat</groupId>
            <artifactId>annotations-api</artifactId>
            <version>6.0.53</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.7.1</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.21.7:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.52.1:exe:${os.detected.classifier}</pluginArtifact>
                    <!--修改生成位置-->
                    <outputDirectory>${basedir}/src/main/java</outputDirectory>
                    <!--生成文件不清空之前的文件-->
                    <clearOutputDirectory>false</clearOutputDirectory>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

生成java文件

grpc-server 服务端开发

引入grpc-api依赖

    <dependencies>
        <dependency>
            <groupId>com.suns</groupId>
            <artifactId>rpc-grpc-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
1. 实现业务接口  添加具体的功能(Mybatis+MySQL)
2. 创建服务端(Netty)
public class HelloServiceImpl extends HelloServerGrpc.HelloServerImplBase{
   //没有返回值是因为,返回值在参数中
   //1. 接受client提交的参数
   //2. 业务调用 service+dao  调用对应的业务功能
   //3. 提供返回值
   @Override
   public void hello(HelloProto.HelloRequest request, StreamObserver<HelloProto.HelloResponse> responseObserver) {
      // 1.接受client提交的参数
      String name = request.getName();
      // 2.业务处理
      System.out.println("name parameter" + name);
      // 3.封装响应
      // 3.1 创建相应对应的构造者
      HelloProto.HelloResponse.Builder builder = HelloProto.HelloResponse.newBuilder();

      // 3.2 填充数据
      builder.setResult(name + " 你好");

      // 3.3 封装响应对象
      HelloProto.HelloResponse response = builder.build();
      responseObserver.onNext(response);
      responseObserver.onCompleted();

   }
}

服务器开发

public class GrpcServer1 {
   public static void main(String[] args) throws IOException, InterruptedException {
      ServerBuilder serverBuilder = ServerBuilder.forPort(9000);

      // 创建一个ServerBuilder实例,并指定监听端口号为9000

      serverBuilder.addService(new HelloServiceImpl());

      // 在ServerBuilder中添加一个HelloServiceImpl实例作为服务提供者

      Server server = serverBuilder.build();

      // 根据ServerBuilder实例创建一个Server对象

      server.start();

      // 启动Server服务

      server.awaitTermination();

      // 等待Server服务停止

   }
}

grpc-client 模块开发

通过开发远端代理对象

  1. 引入grpc-api依赖
    <dependencies>
        <dependency>
            <groupId>com.suns</groupId>
            <artifactId>rpc-grpc-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
  1. 通过远端代理对象 调用服务器服务
  public static void main(String[] args) {
      // 创建 ManagedChannel 对象,用于与服务端建立连接
      ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 9000).
              usePlaintext().build();

      try {
          // 创建 HelloServerGrpc.HelloServerBlockingStub 对象,用于与服务端进行 RPC 调用
          HelloServerGrpc.HelloServerBlockingStub helloService = HelloServerGrpc.newBlockingStub(managedChannel);

          // 创建 HelloProto.HelloRequest 对象,用于构建请求参数
          HelloProto.HelloRequest.Builder builder = HelloProto.HelloRequest.newBuilder();
          HelloProto.HelloRequest helloRequest = builder.setName("suns").build();

          // 调用服务端的 hello 方法,传入请求参数
          HelloProto.HelloResponse helloResponse = helloService.hello(helloRequest);
          String result = helloResponse.getResult();
          System.out.println("result="+result);
      } catch (Exception e) {
          throw new RuntimeException(e);
      } finally {
          managedChannel.shutdown();
      }
  }

注意事项

服务端 处理返回值时

       // 发送响应 ,回传client
       responseObserver.onNext(helloResponse));
       // 告诉客户端完成响应流, 底层返回标记
       responseObserver.onCompleted();   //client就会监听标记[grpc做的]

requestObserver.onNext(helloRequest);
requestObserver.onCompleted()