Define protobuff file
Protocol buffer file is the base template for the communication between the server and the client.
//protobuff version
syntax = "proto3";
//package for protobuff
package calculator;
//package for java
option java_package = "com.thebytecloud.calculator";
//This option will create classes as separate files.
//If this is false, all classes will be created in the same java file.
option java_multiple_files = true;
//Server streaming messages
message PrimeNumberDecompositionRequest {
int64 number = 1;
}
message PrimeNumberDecompositionResponse {
int64 prime_factor = 1;
}
//Service is like a class which has methods for the communication.
service CalculatorService {
//Server streaming rpc
rpc PrimeNumbeDecomposition(PrimeNumberDecompositionRequest) returns (stream PrimeNumberDecompositionResponse) {};
}
Generating the java classes
Running below command in the terminal will generate java files in package com.thebytecloud.calculator (option java_package)
mvn clean generate-sources
Implementing protobuff service methods
package com.thebytecloud.server;
import com.thebytecloud.calculator.*;
import io.grpc.Status;
import io.grpc.stub.StreamObserver;
public class CalculatorServiceImpl extends CalculatorServiceGrpc.CalculatorServiceImplBase {
@Override
public void primeNumbeDecomposition(PrimeNumberDecompositionRequest request, StreamObserver<PrimeNumberDecompositionResponse> responseObserver) {
long number = request.getNumber();
long divisor = 2L;
while(number > 1) {
if(number % divisor == 0){
number = number / divisor;
responseObserver.onNext(
PrimeNumberDecompositionResponse.newBuilder()
.setPrimeFactor(divisor)
.build()
);
System.out.println("Prime Factor = "+ divisor);
} else {
divisor = divisor + 1;
}
}
responseObserver.onCompleted();
}
}
Client Implementation
package com.thebytecloud.client;
import com.thebytecloud.calculator.*;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import io.grpc.stub.StreamObserver;
import java.util.Arrays;
import java.util.Iterator;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class CalculatorClient {
private final ManagedChannel managedChannel;
public CalculatorClient(ManagedChannel managedChannel) {
this.managedChannel = managedChannel;
}
public static void main(String[] args) throws InterruptedException {
String server = "localhost";
int serverPort = 7070;
if(System.getenv("SERVER_PORT") != null)
serverPort = Integer.parseInt(System.getenv("SERVER_PORT"));
if(System.getenv("SERVER") != null)
server = System.getenv("SERVER");
System.out.println("server = " + server+":"+serverPort);
Thread.sleep(2000);
ManagedChannel managedChannel = ManagedChannelBuilder.forAddress(server, serverPort)
.usePlaintext()
.build();
CalculatorClient calculatorClient = new CalculatorClient(managedChannel);
calculatorClient.serverStreamingCall();
}
private void serverStreamingCall() {
long number = 500L;
CalculatorServiceGrpc.CalculatorServiceBlockingStub stub = CalculatorServiceGrpc.newBlockingStub(managedChannel);
PrimeNumberDecompositionRequest request = PrimeNumberDecompositionRequest.newBuilder()
.setNumber(number).build();
final Iterator<PrimeNumberDecompositionResponse> iterator = stub.primeNumbeDecomposition(request);
iterator.forEachRemaining(primeNumberDecompositionResponse -> {
System.out.println("Prime Factor = " + primeNumberDecompositionResponse);
});
}
}
Executing server and client
Executing server and client can be done via IDE or command line. Following are the commands to execute in terminal.
gRPC Server
grpc-java-examples$ mvn clean install
grpc-java-examples$ java -cp target/grpc-java-examples-1.0-SNAPSHOT-jar-with-dependencies.jar com.thebytecloud.server.CalculatorServer
serverBindPort = 7070
Starting gRPC Server...!
Prime Factor = 2
Prime Factor = 2
Prime Factor = 5
Prime Factor = 5
Prime Factor = 5
gRPC Client
grpc-java-examples$ java -cp target/grpc-java-examples-1.0-SNAPSHOT-jar-with-dependencies.jar com.thebytecloud.client.CalculatorClient
server = localhost:7070
Prime Factor = prime_factor: 2
Prime Factor = prime_factor: 2
Prime Factor = prime_factor: 5
Prime Factor = prime_factor: 5
Prime Factor = prime_factor: 5
grpc-java-examples$
Here client sent a number (500) one time and server responds with streaming of prime numbers.