Java实现GRPC

633 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

pom.xml 引入依赖和生成代码插件

依赖
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-netty-shaded</artifactId>
  <version>1.45.1</version>
  <scope>runtime</scope>
</dependency>
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-protobuf</artifactId>
  <version>1.45.1</version>
</dependency>
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-stub</artifactId>
  <version>1.45.1</version>
</dependency>

插件
<build>
    <extensions>
        <extension>
            <groupId>kr.motd.maven</groupId>
            <artifactId>os-maven-plugin</artifactId>
            <version>1.6.2</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.19.2:exe:${os.detected.classifier}</protocArtifact>
                <pluginId>grpc-java</pluginId>
                <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.45.1:exe:${os.detected.classifier}</pluginArtifact>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>compile-custom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>8</source>
                <target>8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

编写proto文件

proto文件放在路径下:src/main/proto 示例文件:

syntax = "proto3";

option java_multiple_files = true;
option java_package = "org.example.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
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;
}

生成代码

分别执行如下操作:

生成的代码位置如下:

将代码拷贝到主工程的相应包下面

编写client

示例代码:

public class HelloWorldClient {

    public static void main(String[] args) throws InterruptedException {
        ManagedChannel channel = null;
        try {
            channel = ManagedChannelBuilder
                    .forTarget("localhost:9999")
                    .usePlaintext()
                    .build();
            GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel);

            HelloRequest req = HelloRequest.newBuilder()
                    .setName("wangyue")
                    .build();
            HelloReply helloReply = stub.sayHello(req);
            System.out.println(helloReply.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
        }
    }
}

编写server

示例代码:

public class HelloWorldServer {

    public static void main(String[] args) throws InterruptedException, IOException {
        final Server server = ServerBuilder.forPort(9999)
                .addService(new GreeterImpl())
                .build()
                .start();

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                server.shutdown().awaitTermination(30, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace(System.err);
            }
        }));

        server.awaitTermination();
    }

    static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
        @Override
        public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
            // 构造参数
            HelloReply reply = HelloReply.newBuilder()
                    .setMessage("hello " + request.getName())
                    .build();

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

总结

  1. client主要包含 channel 和 stu,通过stu调用服务端方法
  2. server主要包含 serviceImpl,通过集成implBase重写各方法,实现业务逻辑