RPC Implementation in Go

What is RPC?

RPC (Remote Procedure Call) is an inter-process communication that exchanges information between various distrubuted systems (servers).
It is a protocol that one program can use to request a service from a program located on som…


This content originally appeared on DEV Community and was authored by Karan Kumar

What is RPC?

RPC (Remote Procedure Call) is an inter-process communication that exchanges information between various distrubuted systems (servers).
It is a protocol that one program can use to request a service from a program located on some other node/server/computer/system on the network without having to udnerstand the network's details.

In simple workds, a computer A can call a function(procedures) in another computer B remotely. Hence, Remote Procedure Call.

The basic steps for the entire process are as:

  1. Client (system A) decides the function name and arguments to send
  2. Client send the same to the RPC Server by dialing the connection
  3. The RPC server receives the function name and arguments
  4. RPC server invokes/executes the function on the remote system B
  5. The client collects the data from the request

As you can see, it is a synchronous process.

image

Go provides a library for both RPC Server and RPC Client
In the above diagram, the client sends the arguments and the reply pointer. Since it is a pointer, the server can modify it as per the request. The client will then use the data filled into the pointer.

Creating an RPC server

Code for this blog can be found here GitHub

Let us now create an RPC server that will send the UTC server time to the RPC client. We will use net/rpc and net/http standard packages for this example.

NOTE The RPC Server and RPC Client should agree upon:

  • Arguments passed
  • Value Returned

And must have exactly same types for both server and client

Let us create an Args struct to hold the arguments received from the client and TimeServer type using which we will register our function on RPC server for clients to run it.

type Args struct {}

type TimeServer int64

Now let us create the GiveTimeServer function which will be invoked from the client.

func (t *TimeServer) GiveServerTime(args *Args, reply *int64) error {
    // Set the value at the pointer got from the client
    *reply = time.Now().Unix()
    return nil
}

Now let us register the methods listening on type TimeServer on the RPC server:

/* server.go */

func main() {
    timeserver := new(TimeServer)
    // Register the timeserver object upon which the GiveServerTime
    // function will be called from the RPC server (from the client)
    rpc.Register(timeserver)
    // Registers an HTTP handler for RPC messages
    rpc.HandleHTTP()
    // Start listening for the requests on port 1234
    listener, err := net.Listen("tcp", ":1234")
    if err !=nil {
        log.Fatal("Listener error: ", err)
    }
    // Serve accepts incoming HTTP connections on the listener l, creating
    // a new service goroutine for each. The service goroutines read requests
    // and then call handler to reply to them
    http.Serve(listener, nil)
}

That's it from the server side.

Creating an RPC client

We will create the struct for Args (its empty in this example). And a reply variable which must have SAME type as that of server.

/* client.go */

package main

import (
    "log"
    "net/rpc"
)

type Args struct {}

func main() {
    // Address to this variable will be sent to the RPC server
    // Type of reply should be same as that specified on server
    var reply int64
    args := Args{}

    // DialHTTP connects to an HTTP RPC server at the specified network
    client, err := rpc.DialHTTP("tcp", "localhost"+":1234")
    if err != nil {
        log.Fatal("Client connection error: ", err)
    }

    // Invoke the remote function GiveServerTime attached to TimeServer pointer
    // Sending the arguments and reply variable address to the server as well
    err = client.Call("TimeServer.GiveServerTime", args, &reply)
    if err != nil {
        log.Fatal("Client invocation error: ", err)
    }

    // Print the reply from the server
    log.Printf("%d", reply)
}

That was pretty straight forward. We just created a client and connected it to the host and port on which server is listening on.

Then we used the Call function to invoke a function tied to the TimeServer type and passed in args and &reply pointer.

Now let us start the server.go program.

$ go run server.go

Now let us start the client.go program and as soon as we do that, we will see the server's reply of it's current UTC time:

$ go run client.go
2021/09/04 18:36:37 1630760797 // ?

That's it. It's that simple. I hope you guys understood how the client and server connection works via RPC server. In future blogs, we will dive deeper into the same topic and cover more on RPC and also GRPC.

Code for this blog can be found here GitHub


This content originally appeared on DEV Community and was authored by Karan Kumar


Print Share Comment Cite Upload Translate Updates
APA

Karan Kumar | Sciencx (2021-09-04T13:23:22+00:00) RPC Implementation in Go. Retrieved from https://www.scien.cx/2021/09/04/rpc-implementation-in-go/

MLA
" » RPC Implementation in Go." Karan Kumar | Sciencx - Saturday September 4, 2021, https://www.scien.cx/2021/09/04/rpc-implementation-in-go/
HARVARD
Karan Kumar | Sciencx Saturday September 4, 2021 » RPC Implementation in Go., viewed ,<https://www.scien.cx/2021/09/04/rpc-implementation-in-go/>
VANCOUVER
Karan Kumar | Sciencx - » RPC Implementation in Go. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/09/04/rpc-implementation-in-go/
CHICAGO
" » RPC Implementation in Go." Karan Kumar | Sciencx - Accessed . https://www.scien.cx/2021/09/04/rpc-implementation-in-go/
IEEE
" » RPC Implementation in Go." Karan Kumar | Sciencx [Online]. Available: https://www.scien.cx/2021/09/04/rpc-implementation-in-go/. [Accessed: ]
rf:citation
» RPC Implementation in Go | Karan Kumar | Sciencx | https://www.scien.cx/2021/09/04/rpc-implementation-in-go/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.