This article focuses on a simple example of gRPC in Java.
preface
We should not only look at the principles and ignore the practice, nor should we focus on the practice and ignore the principle. We should do both!
In the first two articles, “BASIC RPC Series 1: Talking about RPC” and “Basic RPC Series 2: Understanding the Basic Principles and Differences between gRPC and Thrift,” you can get a basic understanding of three important concepts: RPC, gRPC and Thrift. This article will look at the use of gPRC.
GRPC sample
Code: [email protected]: lml200701158 / RPC – study. Git
The project structure
Let’s look at the project structure first:
Generate the protobuf file
helloworld.proto
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.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;
}
Copy the code
You can see that the proto file only defines the format of the input and return values, and the interface to be called. As for the internal implementation of the interface, the file doesn’t care at all.
pom.xml
<? 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>rpc-study</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0. 0</modelVersion>
<artifactId>grpc-demo</artifactId>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.14. 0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.14. 0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.14. 0</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5. 0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.51.</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.51.-1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.14. 0: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>6</source>
<target>6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Copy the code
Protobuf :compile and protobuf:compile- Javanano. When we execute them directly, the file on the left will be generated. GreeterGrpc provides the call interface, and the file function beginning with Hello is mainly to serialize the data, and then process the incoming parameters and return values.
If you want to put the files in target, you can either copy them or use a tool to generate them:
- Download protoc.exe from github.com/protocolbuf…
- Download protoc – gen – GRPC plug-in, download address: jcenter.bintray.com/io/grpc/pro…
Server and client
HelloWorldClient.java
public class HelloWorldClient {
private final ManagedChannel channel;
private final GreeterGrpc.GreeterBlockingStub blockingStub;
private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());
public HelloWorldClient(String host,int port){
channel = ManagedChannelBuilder.forAddress(host,port)
.usePlaintext(true)
.build();
blockingStub = GreeterGrpc.newBlockingStub(channel);
}
public void shutdown(a) throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
public void greet(String name){
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
HelloReply response;
try{
response = blockingStub.sayHello(request);
} catch (StatusRuntimeException e)
{
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
logger.info("Message from gRPC-Server: "+response.getMessage());
}
public static void main(String[] args) throws InterruptedException {
HelloWorldClient client = new HelloWorldClient("127.0.0.1".50051);
try{
String user = "world";
if (args.length > 0){
user = args[0];
}
client.greet(user);
}finally{ client.shutdown(); }}}Copy the code
This is too simple. Connect to the service port and call the sayHello() method.
HelloWorldServer.java
public class HelloWorldServer {
private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());
private int port = 50051;
private Server server;
private void start(a) throws IOException {
server = ServerBuilder.forPort(port)
.addService(new GreeterImpl())
.build()
.start();
logger.info("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run(a) {
System.err.println("*** shutting down gRPC server since JVM is shutting down");
HelloWorldServer.this.stop();
System.err.println("*** server shut down"); }}); }private void stop(a) {
if(server ! =null) { server.shutdown(); }}// Block until the program exits
private void blockUntilShutdown(a) throws InterruptedException {
if(server ! =null) { server.awaitTermination(); }}public static void main(String[] args) throws IOException, InterruptedException {
final HelloWorldServer server = new HelloWorldServer();
server.start();
server.blockUntilShutdown();
}
// The implementation defines a class that implements the service interface
private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage(("Hello " + req.getName())).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
System.out.println("Message from gRPC-Client:" + req.getName());
System.out.println("Message Response:"+ reply.getMessage()); }}}Copy the code
SayHello () ¶ sayHello() ¶ sayHello() ¶ sayHello() ¶
Start the service
Start Server first and return the following:
Restart the Client and return the following:
The Server returns the following:
Afterword.
This Demo looks very simple, but I have been working on it for most of the day. At first, I didn’t know that two different plug-ins need to be executed to generate protobuf. I thought that just click on protobuf:compile, but protobuf:compile-javanano also needs to click on it.
I want to manually generate protobuf files by downloading my own plug-ins, but the manual generation is not done, and the automatic generation is not available. After a long time, I found that the problem is the cache. Finally, just do “Invalidate Caches/Restart”.
I applied for the post with the words “no zuo no die”, but this process still needs experience.
Welcome to more like, more articles, please pay attention to the wechat public number “Lou Zai advanced road”, point to pay attention, don’t get lost ~~