A Guide to Bidirectional Streaming with gRPC

Michael Edenzon
2 min readMar 24, 2020

--

Leverage gRPC’s powerful bidirectional streaming capabilities with a simple Python drawing app and GoLang backend service.

gRPC Logo
gRPC is a powerful API framework developed by Google.

When Google introduced gRPC in 2015, it addressed a lot of the pain points borne by current messaging frameworks (serialization, data contracts, etc.), but it also offered a host of new features that optimize communication between services. One of the most powerful features of Google’s modern messaging framework is bidirectional streaming. In this tutorial, we will develop a simple Python drawing application and GoLang backend service that communicate via gRPC bidirectional stream to mirror the user’s drawing in real time.

Let’s begin by defining the communication between our services. For this, gRPC uses a Protocol Buffer file, which acts as a contract between our client and server. Our backend will consist of one service, Transform, serving up a single remote procedure call, flip, that both receives and returns a gRPC stream of Point messages

Proto files act as a contract between services, and can be compiled to 10+ gRPC supported languages.

Using the Protobuf compiler, we can compile our proto file to any of the gRPC supported languages. For more information on protobuf compiling, checkout grpc.io.

We implement our Transform service by defining each RPC as a method of TransformServer. The flip method reads in a stream of points, and passes them to the graphics package’s Mirror function, where they are flipped along the canvas X-axis. Each newly flipped point is then streamed to the client.

The backend implementation of Transform.Flip receives and returns a stream of points to the client.

The Python GUI paint() function receives a mouse-dragged event, which contains the new mouse coordinates. The mouse coordinates are unpacked and streamed to the backend transform service using the flip method. The call to flip returns a stream of Point objects, which are collected inside of a for-loop, and are drawn to the canvas.

Mouse coordinates are streamed to and from the backend service via gRPC.

To run the application, serve up the backend transform server. With the backend listening on localhost:9901, startup the Python GUI. This will launch a window containing a Tkinter canvas that is listening for click and drag mouse events. As you click and drag your mouse across the canvas, you will see the drawing being mirrored in real time.

The canvas is streaming X and Y coordinates to a backend service via gRPC where they are flipped and streamed back to the canvas in real time.

As you can see, gRPC makes it easy to implement lightweight, powerful streaming capabilities to your services. You can checkout the complete project on GitHub.

In our next tutorial, we will replace our Python GUI with a Vue.js front-end and deploy our services to a Kubernetes cluster.

--

--