gRPC – Server Streaming

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.

Share your love
Nanthakumar
Nanthakumar

I’m a curious engineer, interested in various aspects of software engineering.

Articles: 7