https://geektutu.com/post/quick-go-rpc.html
RPC(Remote Procedure Call) 近程过程调用,计算机通信协议的一种
RPC 下 调用程序 会搁置 client 节点的机器,被调办法子程序 会搁置 Server 节点的机器, client 通过向 Server 发送申请、Server 回调响应来获取 调用程序 的 后果
调用方和执行方别离在不同的机器上
$ mkdir ./goRpc && cd goRpc && go mod init goRpc
$ vi main.go
package main
import("fmt")
type Result struct {
Num int
Ret int
}
type Cal int
func (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}
8
64$
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
}
...
$ mkdir goRPC_server && cd goRPC_server && go mod init goRPC_server
$ vi server.go
package main
import(
"fmt"
"net/rpc"
"net/http"
)
type Result struct {
Num int
Ret int
}
type Cal int
func (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.go
server running on port 8080...
$ mkdir goRPC_client && cd goRPC_client && go mod init goRPC_client
$ vi client.go
package main
import(
"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 main
import(
"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)
}