A gRPC C++ introduction

Andrew Vetovitz
Dec 9, 2018 · 6 min read

by Andrew Vetovitz, Jaspreet Kaur, Mike Lin, Aakash Singh, Kaixin Luo

Image from: grpc.io

gRPC which is short for Google RPC is an application based communication based on protocol buffers. These buffers can communicate language-anonymous (so ruby to python or C++ to Java for example).

gRPC is written in a serialization format. The base use in this tutorial with be protobuf which comes default with the gRPC in the download section below and use the .proto extension. Any serialization language can be used however.

gRPC vs REST

The advantage of gRPC over REST is several. First and foremost gRPC is much quicker than REST because encoding / decoding happens over the users local CPU. Secondly the amount of code one needs to write is less than that of most REST implementations and general type conversion is easier.

C++ Installation

How To Install

Linux:

[sudo] apt-get install build-essential autoconf libtool pkg-configgit clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpccd grpcgit submodule update — initcd grpc/third_party/protobufsudo make install

Windows:

Install Visual Studio 2015 or 2017 (Visual C++ compiler will be used).
Install Git.
Install CMake.Install Active State Perl (choco install activeperl)Install Go (choco install golang)Install yasm and add it to PATH (choco install yasm)powershell git clone — recursive -b ((New-Object System.Net.WebClient).DownloadString(\”https://grpc.io/release\").Trim()) https://github.com/grpc/grpccd grpcgit submodule update — init

MacOS:

[sudo] xcode-select — install(optional) brew install autoconf automake libtool shtoolgit clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpccd grpcgit submodule update — initcd grpc/third_party/protobufsudo make install

Writing a simple request

For this example we will be creating a client that sends a request of two numbers to the server, the server will multiply these two numbers and return the result to the client.

There are 4 parts to writing a protoc buffer request in C++. The Makefile, the client, the server, and the proto file.

First create these 4 files in any editor.

Setup Files

Makefile

gRPC Makefile

The make file when called with make will build both the client and server. gRPC is dependent on several buffer files that will be built with proto in the background as specified in the last 2 build commands before clean.

You should not worry much about what these extra files do, they are simply generated and used by the program however the user never has to interact with them.

Also as a note for users not familiar with more deep Makefile knowledge the $@ takes the name of the command, so in the 2nd and 3rd build commands it would be client and server respectively. The % symbol is a catch all symbol looking for any match. Finally, the $^ symbol uses every file after the build command one at a time, so mathtest.pb.o then mathtest.grpc.pb.o, and finally client.o if looking at the second client build for example.

Proto

gRPC .protoc file

The next file to write is the .proto file. The top line specifies what proto we are using which is proto3. The next line is additional configuration. The name of the package is mathtest in this case which will be the import name later.

The service is what creates the linked between proto and C++ which will later be invoked in our C++ code. This function name is sendRequest that accepts a MathRequest and returns a MathReply.

The messages: MathRequest and MathReply specify the types as well as content of the messages. The numbers in these requests do not specify their values only labeling for the proto file generation. We will set these messages using generated code stub in our C++ code later.

Server

Now we come to putting all the code together.

First import some headers.

gRPC server header

The second and third lines import gRPC headers as well as our .proto file respectively. The next commands set namespaces that will be used for the server as well as our request logic.

Next is the main.

gRPC server main

Not much to say here.

Lets look at the Run() command.

gRPC server run

The run command creates a port on localhost 5000 as well as instantiates a class called MathServiceImplementation which we will create in a second. This contains our gRPC logic. We then instantiate a server called builderand bind our service as well as the port to this server. Since we are not using SSL we use insecure credentials. After that we start the server with a smart pointer and wait to hear from the client.

Lets look at MathServiceImplementation finally.

gRPC server service

This class extends our .protoc file MathTest Service and will contain our logic. From our .proto file we had a sendRequest function which we will be adding logic to here. The sendRequest returns a status such as 200, 404, 500 ect… We are overriding this function in order to add our arithmatic logic. The request from the .proto file takes 2 values, a and b which we pull out in the overrid body. Then we set the value of result in MathReply using the generate function stub set_result(value) which we set value to be a * b. There are several generated function stubs that the protoc compiler will create, this is just one of them. Finally we return Status::OK to signal the message has been creates and send by the gRPC protocol.

Putting it all together one should get a file that looks like this.

gRPC server file

Client

Lets start off with the headers in main again.

gRPC client header and main

The only difference between the server is that we use different grpc namespaces this time.

For the Run function.

gRPC client run

Here we connect to port localhost port 5000 which is what the server is running on as well as instantiate a class called MathTestClient. From there we declare variables and call function sendRequest (not the same function used in our proto file) passing the two numbers a and b which will be sent to the server. Finally we print the result from the server.

Looking at the MathTestClient class

gRPC client service

Here we do not need to override the request since we are simply sending and receiving the results request, adding no new logic like the server does. In the sendRequest function we set a and b with protoc generated c++ function set_* stubs. Afterwards we create the reply and use our MathTest proto stub to invoke sendRequest (this one is generated from our proto file) to the server.

Once the status returns we check if status is successful and return the result of our reply which is the multiplication of a and b.

The result of all the steps above will be a file looking like the one below

gRPC client file

Running everything

After creating all the files one only has to run

make

On one terminal run

./server

On another terminal run

./client

On the client terminal you should see

Answer received: 5 * 10 = 50

Benchmark

Below is a table of total time in seconds to complete x specified requests from the same program above written in both gRPC and REST. You can determine if gRPC from this perspective is worth the speedup it provides.

Total Time in seconds to Complete X Requests

gRPC seems to be 4 times faster here, but different server logic and data size amounts could vary this value.

Closing

While gRPC can be a little difficult to setup at first once the user gets going they can be simpler in the long run to write over REST requests especially for C++. while most rest services are quicker to get up and running if speed is a requirement the extra time to prepare gRPC can be worth it. Also, since more content is being driven over the web year over year being able to support http2 can be worth it for the asynchronous gains used in these requests. One more note is in this article the group did not look at asynchronous requests. So the above Benchmark table could potentially show even more gains in performance if that was explored as well.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade