Listen gRPC and HTTP requests on the same port
As I said before, I'm working on a great project called Teresa written in Golang that uses gRPC. To facilitate monitoring and health checks, we decided to expose a health check endpoint with HTTP standard protocol instead of gRPC, but how can we expose those services on the same port?
There is a great project called cmux that can help us like a charm. According to cmux documentation:
cmux is a generic Go library to multiplex connections based on their payload. In other words, you create a common
net.Listener and define some rules to route your requests to the right server.
Talk is cheap, so let's build a toy example to show cmux in action beginning with a gRPC handler:
Nothing special here, right? Now, a "ping-pong" HTTP handler:
Ok, now is the time to “up and running”. We’ll create the main listener, a new connection multiplexer (aka cmux instance), new listeners that accept only connections that respect some rules like protocol, headers, etc (under the hood, those listeners use the same main listener we had created before) and finally start our server.
Done! Now you can run both servers (gRPC and HTTP) on the same TCP port. You can check the complete example on Github.
There is another way to deal with gRPC and HTTP on the same port without a third party framework (like cmux), but it’s a subject to another post.
Do you remember the problem I described in my last post? Well, now it's solved, because I started to accept HTTP requests.