An example of RPC remote call in go language net package

Time:2020-1-15

The RPC package provides a method to enter the external method of an object through a network or other I / O connection. A server registers an object and marks it as a service with a visible object type name. Once registered, the object’s external methods can be called remotely. A server can register multiple objects of different types, but cannot register multiple objects of the same type.

Only methods that meet these criteria are considered visible by remote calls; other methods are ignored:

-Method is externally visible.
-Method has two parameters whose types are externally visible.
-The second parameter of the method is a pointer.
-Method has return type error

1、 HTTP based RPC

Server:

package main;

 

import (

  "net/rpc"

  "net/http"

  "log"

)

 

//Go supports RPC at three levels: TCP, HTTP and jsonrpc

//RPC of go only supports the interaction between the server and the client developed by go, because it adopts gob coding

 

//Note that the field must be an export

type Params struct {

  Width, Height int;

}

 

type Rect struct{}

 

//Function must be exported

//There must be two export type parameters

//The first parameter is the receive parameter

//The second parameter is returned to the client parameter, which must be of pointer type

//Function also has a return value error

func (r *Rect) Area(p Params, ret *int) error {

  *ret = p.Width * p.Height;

  return nil;

}

 

func (r *Rect) Perimeter(p Params, ret *int) error {

  *ret = (p.Width + p.Height) * 2;

  return nil;

}

 

func main() {

  rect := new(Rect);

  //Register a rect service

  rpc.Register(rect);

  //Binding service processing to HTTP protocol

  rpc.HandleHTTP();

  err := http.ListenAndServe(":8080", nil);

  if err != nil {

    log.Fatal(err);

  }

}

Client:

package main;

 

import (

  "net/rpc"

  "log"

  "fmt"

)

 

type Params struct {

  Width, Height int;

}

 

func main() {

  //Connect to remote RPC service

  rpc, err := rpc.DialHTTP("tcp", "127.0.0.1:8080");

  if err != nil {

    log.Fatal(err);

  }

  ret := 0;

  //Call remote method

  //Note that the third parameter is the pointer type

  err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);

  if err2 != nil {

    log.Fatal(err2);

  }

  fmt.Println(ret);

  err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);

  if err3 != nil {

    log.Fatal(err3);

  }

  fmt.Println(ret);

}

2、 RPC based on TCP

Server:

package main;

 

import (

  "net"

  "log"

  "net/rpc"

)

 

//Note that the field must be an export

type Params struct {

  Width, Height int;

}

 

type Rect struct{}

 

func (r *Rect) Area(p Params, ret *int) error {

  *ret = p.Width * p.Height;

  return nil;

}

 

func (r *Rect) Perimeter(p Params, ret *int) error {

  *ret = (p.Width + p.Height) * 2;

  return nil;

}

 

func chkError(err error) {

  if err != nil {

    log.Fatal(err);

  }

}

 

func main() {

  rect := new(Rect);

  //Register RPC service

  rpc.Register(rect);

  //Get tcpaddr

  tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");

  chkError(err);

  //Listening port

  tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);

  chkError(err2);

  //Loop processing connection request

  for {

    conn, err3 := tcplisten.Accept();

    if err3 != nil {

      continue;

    }

    //Using goroutine to handle RPC connection requests separately

    go rpc.ServeConn(conn);

  }

}

Client:

package main;

 

import (

  "net/rpc"

  "fmt"

  "log"

)

 

type Params struct {

  Width, Height int;

}

 

func main() {

  //Connect to remote RPC service

  //Dial is used here, and DialHTTP is used in HTTP mode. Other codes are the same

  rpc, err := rpc.Dial("tcp", "127.0.0.1:8080");

  if err != nil {

    log.Fatal(err);

  }

  ret := 0;

  //Call remote method

  //Note that the third parameter is the pointer type

  err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);

  if err2 != nil {

    log.Fatal(err2);

  }

  fmt.Println(ret);

  err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);

  if err3 != nil {

    log.Fatal(err3);

  }

  fmt.Println(ret);

}

3、 JSON RPC mode

The way of jsonrpc is that the data is encoded by JSON, not by gob.

Server:

package main;

 

import (

  "net"

  "log"

  "net/rpc"

  "net/rpc/jsonrpc"

)

 

//Note that the field must be an export

type Params struct {

  Width, Height int;

}

 

type Rect struct{}

 

func (r *Rect) Area(p Params, ret *int) error {

  *ret = p.Width * p.Height;

  return nil;

}

 

func (r *Rect) Perimeter(p Params, ret *int) error {

  *ret = (p.Width + p.Height) * 2;

  return nil;

}

 

func chkError(err error) {

  if err != nil {

    log.Fatal(err);

  }

}

 

func main() {

  rect := new(Rect);

  //Register RPC service

  rpc.Register(rect);

  //Get tcpaddr

  tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");

  chkError(err);

  //Listening port

  tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);

  chkError(err2);

  for {

    conn, err3 := tcplisten.Accept();

    if err3 != nil {

      continue;

    }

    //Using goroutine to handle RPC connection requests separately

    //Here we use jsonrpc for processing

    go jsonrpc.ServeConn(conn);

  }

}

Client:

package main;

 

import (

  "fmt"

  "log"

  "net/rpc/jsonrpc"

)

 

type Params struct {

  Width, Height int;

}

 

func main() {

  //Connect to remote RPC service

  //Use jsonrpc.dial here

  rpc, err := jsonrpc.Dial("tcp", "127.0.0.1:8080");

  if err != nil {

    log.Fatal(err);

  }

  ret := 0;

  //Call remote method

  //Note that the third parameter is the pointer type

  err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);

  if err2 != nil {

    log.Fatal(err2);

  }

  fmt.Println(ret);

  err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);

  if err3 != nil {

    log.Fatal(err3);

  }

  fmt.Println(ret);

}

The above is the whole content of this article. I hope it will help you in your study, and I hope you can support developepaer more.

Recommended Today

PHP realizes UnionPay business H5 payment

UnionPay business H5 payment interface document: document address 1: H5 payment interface address: 1: Alipay payment Test address: http://58.247.0.18:29015/v1/netpay/trade/h5-pay Official address: https://api-mop.chinaums.com/ 2: UnionPay payment Test address: http://58.247.0.18:29015/v1/netpay/uac/order Official address: https://api-mop.chinaums.com/ 2: Basic parameters required by the interface The interface uses get parameters. After the interface parameters are directly put into the interface address, the […]