Go - RPC

参考

https://geektutu.com/post/quick-go-rpc.html

RPC简介

RPC(Remote Procedure Call)近程过程调用,计算机通信协议的一种RPC下 调用程序 会搁置client节点的机器,被调办法子程序 会搁置Server节点的机器, client通过向Server发送申请、Server回调响应来获取 调用程序 的 后果调用方和执行方别离在不同的机器上

本地调用的例子

$ mkdir ./goRpc && cd goRpc && go mod init goRpc$ vi main.go
package mainimport(    "fmt")type Result struct {    Num int    Ret int}type Cal intfunc (cal *Cal) Square(num int) *Result{    return &Result{        Num: num,        Ret: num*num,    }}func main(){    c := new(Cal)    ret := c.Square(8)    fmt.Println(ret)    fmt.Println(ret.Num)    fmt.Println(ret.Ret)}
$ go run main.go                                                                           &{8 64}864$ 

RPC被调用子办法须要满足的条件

func (t *T) MethodName(argType T1, replyType *T2) error
办法类型(T)是导出的(首字母大写)办法名(MethodName)是导出的办法有2个参数(argType T1, replyType *T2),均为导出/内置类型办法的第2个参数一个指针(replyType *T2)办法的返回值类型是 error
// 革新Square函数...func (cal *Cal) Square(num int, ret *Result) error{    ret.Num = num    ret.Ret = num * num    return nil}...

RPC 服务与调用

创立服务端

$ mkdir goRPC_server && cd goRPC_server && go mod init goRPC_server$ vi server.go
package mainimport(    "fmt"    "net/rpc"    "net/http")type Result struct {    Num int    Ret int}type Cal intfunc (cal *Cal) Square(num int, ret *Result) error{    ret.Num = num    ret.Ret = num * num    return nil}func main(){    rpc.Register(new(Cal))    rpc.HandleHTTP()    fmt.Println("server running on port 8080...")    if err := http.ListenAndServe(":8080", nil);err != err{        fmt.Println("error: ", err)    }}
$ go run server.goserver running on port 8080...

创立客户端(同步调用)

$ mkdir goRPC_client && cd goRPC_client && go mod init goRPC_client$ vi client.go
package mainimport(    "fmt"    "net/rpc")type Result struct {    Num int    Ret int}func main(){    var ret Result    client, err := rpc.DialHTTP("tcp", ":8080")    if err != nil{        fmt.Println("create rpc client error: ", err)        return    }    if err := client.Call("Cal.Square", 8, &ret);err != nil{        fmt.Println("failed to call Cal.Square: ", err)        return    }    fmt.Printf("success to call Cal.Square of 8: %d\n", ret.Ret)}
$ go run client.go                     success to call Cal.Square of 8: 64

创立客户端(异步调用)

package mainimport(    "fmt"    "net/rpc")type Result struct {    Num int    Ret int}func main(){    var ret Result    client, err := rpc.DialHTTP("tcp", ":8080")    if err != nil{        fmt.Println("create rpc client error: ", err)        return    }    asyCall := client.Go("Cal.Square", 8, &ret, nil)    <-asyCall.Done // 阻塞以后程序直到 RPC 调用完结    fmt.Printf("success to call Cal.Square of 8: %d\n", ret.Ret)}