This article describes the process of using gRPC in Java. Generally speaking, it consists of the following three steps
1) Define the services provided in the. proto file
2) Compile files using protocol buffer compiler
3) Use gRPC API to create and invoke the server and client.
Download and install the required software
1)Protocol Buffers
Structured data serialization mechanism
https://github.com/protocolbuffers/protobuf/releases
Use examples:
protoc --java_out=./ *.proto
2)protoc-gen-grpc-java
Used to generate RPC communication code
http://jcenter.bintray.com/io/grpc/protoc-gen-grpc-java/
Using an example [using the Protobuf-Plugin mechanism]:
protoc --plugin=protoc-gen-grpc-java=protoc-gen-grpc-java-1.19.0-windows-x86_64.exe --grpc-java_out=./ *.proto
Building gRPC with Maven
1) Modify pmo.xml
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <protobuf.version>3.7.0</protobuf.version> <grpc.version>1.19.0</grpc.version> </properties> <dependencies> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty-shaded</artifactId> <version>${grpc.version}</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> <!-- Ensure that the runtime version number and protoc Version number matching (or updating) --> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>${protobuf.version}</version> </dependency> <!-- If you want to use Imagination JsonFormat Such a feature adds the following dependencies--> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java-util</artifactId> <version>${protobuf.version}</version> </dependency> </dependencies> <build> <extensions> <extension> <!-- Reference to the description of the plug-in https://github.com/trustin/os-maven-plugin --> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.6.1</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <!-- proto The path of the file --> <!-- <protoSourceRoot>${project.basedir}/src/main/resources/proto</protoSourceRoot> --> <!-- After compilation java Output path of file,Default is ${project.build.directory}/generated-sources/protobuf/java --> <!--<outputDirectory> ${project.build.directory}/generated-sources/protobuf/java</outputDirectory> --> <!-- Formulate protoc Compiler path --> <!-- <protocExecutable></protocExecutable> --> <!-- Define the generated java File output path --> <!--<outputDirectory>${project.build.sourceDirectory}</outputDirectory> --> <!--Set whether to generate java Clean up before the document outputDirectory File, default value true,Set to false It also overwrites files with the same name. --> <clearOutputDirectory>false</clearOutputDirectory> <protocArtifact>com.google.protobuf:protoc:${protobuf.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>
By default, the plug-in looks for proto files in the src/main/proto path. Any subfolder under the path will be used as the package path in the proto file.
2) Create proto file under src/main/proto
syntax = "proto3"; package com.ultrapower.ioss.webdriver.proto; option java_outer_classname = "HarLogRpc"; message HarLogResovleRequest{ string url = 1 ; string file_name = 2; string file_dir = 3; string context = 4; } message HarLogResovleResponse{ int32 code = 1 ; } service HarLogService{ rpc ResovleHarLog(HarLogResovleRequest) returns (HarLogResovleResponse); }
3) Compile files
mvn protobuf:compile //or mvn compile
The following two folders are generated under target generated-sources protobuf
The Java folder contains the message we defined, while grpc-java stores the service that both the server and the client use.
Based on the proto file above, two java files are generated
1. HarLogService Grpc. Java is located under grpc-java 2. HarLogRpc.java is under java
4) Complete the code
First we implement the server-side code
package com.ultrapower.ioss.webdriver.proto; import com.ultrapower.ioss.webdriver.proto.HarLogRpc.HarLogResovleRequest; import com.ultrapower.ioss.webdriver.proto.HarLogRpc.HarLogResovleResponse; import io.grpc.stub.StreamObserver; public class HarLogServiceImpl extends HarLogServiceGrpc.HarLogServiceImplBase { @Override public void resovleHarLog(HarLogResovleRequest request, StreamObserver<HarLogResovleResponse> responseObserver) { String fileName = request.getFileName() ; responseObserver.onNext(HarLogResovleResponse.newBuilder().setCode(200).build()); //Represents that the process has been completed responseObserver.onCompleted(); } }
Start the server
public class Startup { private Server server; private int port = 8888; public void start() throws IOException { server = ServerBuilder.forPort(port) .addService(new HarLogServiceImpl()) .build() .start(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { Startup.this.stop(); } }); } private void stop() { if (server != null) { server.shutdown(); } } private void blockUntilShutdown() throws InterruptedException { if (server != null) { server.awaitTermination(); } } public static void main(String[] args) throws Exception { final Startup server = new Startup(); server.start(); server.blockUntilShutdown(); } }
Creating a Java-based client
public class Client { private final ManagedChannel channel; private final HarLogServiceGrpc.HarLogServiceBlockingStub blockingStub; /** * Create a server-side connection and create a "pile" * */ public Client(String host, int port) { channel = NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT).build(); blockingStub = HarLogServiceGrpc.newBlockingStub(channel); } public void shutdown() throws InterruptedException { channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); } /** * Send a request to the server * */ public void resovleHarLog() { try { HarLogResovleRequest request = HarLogResovleRequest.newBuilder().setUrl("www.baidu.com").setFileName("test").build(); HarLogResovleResponse response = blockingStub.resovleHarLog(request) ; System.out.println("result from server: " + response.getCode()); } catch (RuntimeException e) { System.out.println("RPC failed:" + e.getMessage()); return; } } public static void main(String[] args) throws Exception { Client client = new Client("127.0.0.1", 8888); try { client.resovleHarLog(); } finally { client.shutdown(); } } }