DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Giving AI Agents Safe Access to Legacy Systems: Introducing legacy2mcp
  • Adding Graph Retrieval to a RAG Pipeline With Python
  • Building a Product Recommendation Engine With Neo4j — No ML Library Required
  • 6 Techniques To Reduce LLM API Costs With the Python Library

Trending

  • Beyond @Transactional: Solving the Dual-Write Problem in Distributed Microservices
  • Multi-Agent Orchestration on AWS With AgentCore Runtime and A2A
  • Agentic Systems and Design Patterns
  • Building a Software Factory With AI Agents and Workflows

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Languages
  4. gRPC Sample in C++ and Python

gRPC Sample in C++ and Python

Google recently open sourced gRPC, which adds remote procedure calls on top of Protobufs, including code generation and serialization that works with multiple languages.

By 
Eli Bendersky
·
Mar. 21, 16 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
14.6K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

almost exactly five years ago, i posted a code sample of using the protocol buffers library for client-server communication. even though protobufs are very convenient for serializing/deserializing data in multiple languages, i had to roll my own networking layer for the actual client and server.

i resorted to using boost::asio (which is on its way into c++17 , by the way) to ease on the details in the c++ server. but even boost::asio won't do everything for you; for example, actually putting serialized protobufs on the wire requires additional mechanisms like length-prefixing and a special enumeration value in every message to select the request type ("message polymorphism"). it's a lot of custom coding for a problem that was solved long ago.

the reality is that i was hand-rolling a simple rpc implementation. now, in 2016, it's no longer necessary as google has recently open-sourced grpc , the yang to the protocol buffers yin. grpc expands the protobuf specification to define rpc services and then auto-generates server and client code from them, taking care of the whole networking layer. all you have remaining is to implement your custom application logic. grpc is very new (still in beta, and only released last year), but it's a rewrite of the google-internal stubby system which has been used for at least a decade for the same purpose. google appears to be committed to maintaining grpc in the long haul since it uses it as the api for some of its cloud offerings.

grpc diagram from www.grpc.io

the code for the new sample is available in full here . here is the message/service definition:

syntax = "proto3";

package stringdb;

service stringdb {
 // get the value stored on the server for a given key
 rpc getvalue (getvaluerequest) returns (getvaluereply) {}

 // set the server's value for a given key
 rpc setvalue (setvaluerequest) returns (setvaluereply) {}

 // count the size of the server's value for a given key
 rpc countvalue (countvaluerequest) returns (countvaluereply) {}
}

message getvaluerequest {
 string key = 1;
}

message getvaluereply {
 // empty string returned when key not found on the server.
 string value = 1;
}

message setvaluerequest {
 string key = 1;
 string value = 2;
}

message setvaluereply {
 // returns the value.
 string value = 1;
}

message countvaluerequest {
 string key = 1;
}

message countvaluereply {
 // returns the size of the value, in bytes. if key isn't found on the server,
 // returns -1.
 int64 count = 1;
}

it's longer than before because now it also specifies the service, which is an rpc contract that the server and the client implement. we get a lot of buck from grpc for this simple definition, because now the networking server logic is rolled into ~10 lines of c++ code. the vast majority of the code is spent implementing the server-side rpc methods. here's an example:

grpc::status getvalue(grpc::servercontext* context,
 const stringdb::getvaluerequest* request,
 stringdb::getvaluereply* reply) override {
 // get data from request; do work; populate reply; return a status.
 return grpc::status::ok;
}

on the python side, all the client has to do is:

channel = implementations.insecure_channel('localhost', port)
stub = stringdb_pb2.beta_create_stringdb_stub(channel)

...

# invoke methods on the stub...

request = stringdb_pb2.countvaluerequest(key=key)
response = stub.countvalue(request, timeout_seconds)
return response.count

it's quite incredible how much code grpc saves you from writing... just compare to the previous sample!

but, that's not all. what i have here is a very simplistic service. grpc gives us many advanced features out of the box that would take serious time investment to implement:

  • http/2 support out of the box (reduced latency over traditional http servers)
  • multi-language support for the network layers, not only data (de)serialization. want to write your server in go and client in objective-c? no problem
  • performance through thread pools and other server implementation variations
  • authentication with ssl/tls or oauth
  • blocking and non-blocking servers and clients
  • streaming
  • flow-control
  • cancelation and timeouts on rpc calls

installing grpc on an ubuntu box was pretty simple. i just went through the instructions in their install.md file to build and install it from source. the python plugin and related code can be installed with pip (be sure to use a virtualenv). one small wrinkle i ran into is that you also have to "make install" the protobuf library (pulled in as a git submodule by the grpc checkout process). even though grpc's makefile compiles it, it doesn't install it.

link to the code .

Python (language)

Published at DZone with permission of Eli Bendersky. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Giving AI Agents Safe Access to Legacy Systems: Introducing legacy2mcp
  • Adding Graph Retrieval to a RAG Pipeline With Python
  • Building a Product Recommendation Engine With Neo4j — No ML Library Required
  • 6 Techniques To Reduce LLM API Costs With the Python Library

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook