Cap'n Proto: https://capnproto.org/ go-capnp: https://github.com/capnproto/go-capnp
This is just a place for me to learn some go and stand up a server that I can send a string to and get one back.
I wrote this up because I'm new to Go and struggled to follow the existing docs a bit. This should get you going from scratch. You can of course just clone down this repo, but if you want to know the work/steps that went into it, read on!
-
Create a go.mod file in a
server
dir with these contents// server/go.mod module server go 1.19 require capnproto.org/go/capnp/v3 v3.0.0-alpha.28
and run
go mod tidy
(you could also rungo mod init server
and then add the require on the last line followed bygo mod tidy
) -
Create a
.capnp
file at the top-level dir (for client and server to share) and use the capnp compiler to put the generated go code into theserver/hello_world
dircapnp compile -I$GOPATH/src/capnproto.org/go/capnp/std -ogo:./server/hello_world hello_world.capnp --verbose
This can be a tricky step, you've got to install capnp executable (follow instructions on capnproto.org) and point to an install of
go-capnp
(they have instructions for this, you can clone it or you can use go to install in the GOPATH like I did). Then you specify the generatorgo
and the output dir./server/hello_world
.The result should be a
hello_world.capnp.go
file underserver/hello_world
. -
Implement methods in
hello_world.go
and add that to server/hello_world. See file in source for full details, but the gist is:- Use the same package as what was generated by go-capnp (
hello_world
) - Make a struct that does not match any existing struct names that can implement the server interface. This is easy if you just leave out the underscores
type GreeterServer struct{}
instead oftype Greeter_Server struct{}
- Add a method to it to implement the interface
func (GreeterServer) Greet(ctx context.Context, call Greeter_greet) error
- See docs on creating messages: https://github.com/capnproto/go-capnp/blob/main/docs/Working-with-Capn-Proto-Types.md
- Use the same package as what was generated by go-capnp (
-
Make a
main
package with the TCP server in it atmain/main.go
like the one in this repo. There are a lot of details in there, much of it is in the docs but some I had to piece together myself and I don't know if it's great, being a newcomer and all: https://github.com/capnproto/go-capnp/blob/main/docs/Remote-Procedure-Calls-using-Interfaces.md
I happen to want to use Python as my client, so I'll include that here for completeness though you are welcome to implement whatever client you like. The python client does not require code generation, it dynamically creates methods/types (though you can generate a stubs file to help with type hinting).
-
The python lib / docs are here: https://github.com/capnproto/pycapnp/ for getting installed and started.
-
I just have a bare-bones client.py here. The tricky bit is handling the go import in our
.capnp
file. You have two options a. Update hello_world.capnp to have relative reference to go.capnp (this is the top comment in hello_world.capnp) b. Callcapnp.load
in the client with animports
arg which adds the location ofgo.capnp
to the search paths (this is used now)Both require you help python find
go.capnp
which is annoying but just how things work.