RPC原理图
- 客户端Stub: 客户端存根
- 服务端Stub: 服务端存根
RPC技术架构
服务端:server.go
package main
import (
"math"
"net"
"net/http"
"net/rpc"
)
type MathUtil struct {
}
// 该方法向外暴露:提供计算圆形面积的服务
func (mu *MathUtil) CalculateCircleArea(req float32, resp *float32) error {
*resp = math.Pi * req * req
return nil
}
func main() {
// 1. 初始化指针数据类型
MathUtil := new(MathUtil) // 初始化指针数据类型
// 2.调用net/rpc包的功能将服务对象进行注册
err := rpc.Register(MathUtil)
if err != nil {
panic(err.Error())
}
// 3.通过该函数把mathUtil中提供的服务注册到HTTP协议上,方便调用者可以利用http的方法进行数据传输
rpc.HandleHTTP()
// 4.在特定的端口进行监听
listen, err := net.Listen("tcp", ":8081")
if err != nil {
panic(err.Error())
}
http.Serve(listen, nil)
}
客户端:client.go
package main
import (
"fmt"
"net/rpc"
)
// 客户端逻辑
func main() {
client, err := rpc.DialHTTP("tcp", "localhost:8081")
if err != nil {
panic(err.Error())
}
var req float32
req = 3
// 同步调用方式
// var resp *float32
// err = client.Call("MathUtil.CalculateCircleArea", req, &resp)
// if err != nil {
// panic(err.Error())
// }
// fmt.Println("resp: ", *resp)
// 异步调用方式
var respSync *float32
syncCall := client.Go("MathUtil.CalculateCircleArea", req, &respSync, nil)
replayDone := <-syncCall.Done
fmt.Println("replayDone: ", replayDone)
fmt.Println("respSync: ", *respSync)
}