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)}