48
RPC with Go, what is it?
OK, so we're going to have a look at RPC with Go. So what is RPC? RPC (remote procedure call) is a distributed computing concept where a call and response mechanism applies to the execution of a function to achieve an outcome and receive a result.
But what does that mean? Well, we could look at it as follows:

net/rpc
and net/jsonrpc
.We're going to have a project that contains two sub-projects, so let's create a folder for the project and within it create two subfolders,
client
and server
. Ideally we now have a structure that looks like the following:
rpc-banner-demo
├── client
│ └── main.go
└── server
└── main.go
We're going to create an RPC server with a function that returns a message that could be used as a banner message or some other purpose for which you need to return a string.
package main
import (
"log"
"net"
"net/http"
"net/rpc"
)
// an RPC server in Go
type Args struct{}
type BannerMessageServer string
func (t *BannerMessageServer) GetBannerMessage(args *Args, reply *string) error {
*reply = "This is a message from the RPC server"
return nil
}
func main() {
// create and register the rpc
banner := new(BannerMessageServer)
rpc.Register(banner)
rpc.HandleHTTP()
// set a port for the server
port := ":1122"
// listen for requests on 1122
listener, err := net.Listen("tcp", port)
if err != nil {
log.Fatal("listen error: ", err)
}
http.Serve(listener, nil)
}
Things to note:
GetBannerMessage
of the BannerMessageServer
type.Now we create the client that will call our server and handle/use the response and result.
package main
import (
"log"
"net/rpc"
)
// rpc client
type Args struct{}
func main() {
hostname := "localhost"
port := ":1122"
var reply string
args := Args{}
client, err := rpc.DialHTTP("tcp", hostname+port)
if err != nil {
log.Fatal("dialing: ", err)
}
// Call normally takes service name.function name, args and
// the address of the variable that hold the reply. Here we
// have no args in the demo therefore we can pass the empty
// args struct.
err = client.Call("BannerMessageServer.GetBannerMessage", args, &reply)
if err != nil {
log.Fatal("error", err)
}
// log the result
log.Printf("%s\n", reply)
}
Things to note:
localhost
and :1122
in our demo case. service.function
and the reply will be assigned to the address of of our local variable reply
.OK so now we're in a position to run our code and see this magic unfold before our eyes. There is a couple of options here, I'm opting to run both programs from the root folder of our project. We'll need two terminals, so here you can split your terminal in VSCode.
in one run
go run server/main.go
, in the other run go run client/main.go
and marvel at your resultsI hope you found this fairly trivial RPC example useful as a RPC client/server setup overview and as a potential springboard to your own functions and setups that actually have a real purpose.
Best wishes.
48