I’m finding myself in need of a protocol to communicate between two processes, and I can’t find what I want.
The two processes will communicate over a Unix Socket in a peer-to-peer fashion. This is a very straightforward situation that I thought I would be able to handle trivially.
It is, of course, very easy for two processes to exchange bytes over a unix socket. The web is full of tutorials on writing various “Hello World” and echo services over unix sockets.
What I found to be missing is the bits in between. On a streaming unix socket, there are no inherent message frames, or message request-response paradigms, so it’s entirely up to you to work that out.
There are a few such protocols available, but most seem to be too heavy, or are less than ideal for one reason or another.
What I Am Looking For
Here is what I would like:
- Lean, fast, lightweight. This needs to run on low power devices.
- Message payloads should be binary or plain text. Not JSON. I want full flexibility to pass anything as payload, and I do not want to coerce binary data into a JSON string.
- There are multiple different services at each end of the connection, so the protocol should include metadata that identifies the service that should receive the message without decoding the payload.
- The protocol should pass metadata that tells the service how to handle the payload. Think of this as the function that the service has to call.
- Protocol should support request/response, and request/multi-response (to get rows from a DB as individual messages instead of one giant lump).
- All messages passed should get a response indicating whether its processing was successful or not.
- Support multiple simultaneous asynchronous messages.
- Go and Typescript implementations.
While I am itching to roll my own (being in over my head yet learning something along the way is an appealing cocktail of emotions), I did look into existing solutions.
NetStrings is the simplest of protocols. It fails to meet my needs but I absolutely love the minimalism.
When I first looked into this I thought I could just use NetStrings. But once I added the need to forward payloads to different services, and to pass other metadata (including message ids) I found myself creating “Netstrings With Metadata” and it got complicated.
MsgPack is appealing, so its RPC extension should be as well, right? Turns out it’s a bit underwhelming for my needs: it only supports request-response.
WAMP is a websocket subprotocol, but it can be used over unix sockets as well. It looks like it is essentially what I need. The Go project that supports it is called Nexus, and it looks solid if maybe more than what I need.
If I fail at rolling my own this is a good candidate to rescue me.
According to their home page STOMP “comes from the http school of design”, and taking a very brief look at their protocol, I do see the family resemblance. I’m looking for something that uses fewer messages. I don’t need a lot of connection stuff because I’m essentially hooking up two processes, that’s it.
ØMQ is rad, and venerable, and I’ve always been interested in it but never got to use it. Looking at all it can do, it seems overkill for my needs right now.
I should look more at it, I just have a resistance to “everything and the kitchen sink” type of solutions to small problems.
I came across this so I’m including it, but it looks dated. No support for Go means it’s DOA as far as I’m concerned. Moving on.
Dated, and way too verbose (it uses a subset of XML), but I found some interesting pages about protocol design on their site.
This is an enterprise grade standard. Looks like it’s too much for what I need. The bare minimum message is already much bigger than what I have in mind.
This caught my attention because the acronym comes up in home automation systems. But it’s a protocol for telemetry, so not what I’m looking for in this context.
What Did I Miss?
If you know of something I should look at please ping me.
I started an implementation of something that might work in Go. It’s rough and I’m not very confident about it. So I keep going back to learning more about existing protocols to see if it’s less trouble to adapt to something non-ideal than to roll my own.
Expect more posts about this as I work through the #100DaysToOffload challenge. (Today was day 4.)