模拟RPC调用
文件目录结构server.go
package main
import (
"./param"
"math"
"net"
"net/http"
"net/rpc"
)
//数学计算
type MathUtil struct {
}
//该方法向外暴露:提供计算圆形面积的服务
func (mu *MathUtil) CalculateCircleArea(req float32, resp *float32) error {
*resp = math.Pi * req * req //圆形的面积 s = π * r * r
return nil //返回类型
}
func (mu *MathUtil) Add(param param.AddParma, resp *float32) error {
*resp = param.Args1 + param.Args2 //实现两数相加的功能
return nil
}
//main 方法
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", ":8881")
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:8881")
if err != nil {
panic(err.Error())
}
var req float32 //请求值
req = 5
//var resp *float32 //返回值
////同步的调用方式
//err = client.Call("MathUtil.CalculateCircleArea", req, &resp)
//if err != nil {
// panic(err.Error())
//}
//fmt.Println(*resp)
var respSync *float32
//异步的调用方式
syncCall := client.Go("MathUtil.CalculateCircleArea", req, &respSync, nil)
//fmt.Println(*respSync)
replayDone := <-syncCall.Done // 从channel里读取,阻塞在这里,必须等到syncCall拿到数据。达到同步的效果
fmt.Println(replayDone) // chan 类型
fmt.Println(*respSync)
}
client2.go
多参数
把多参数封装入结构体中
package main
import (
"./param"
"fmt"
"net/rpc"
)
func main() {
client, err := rpc.DialHTTP("tcp", ":8881")
if err != nil {
panic(err.Error())
}
var result *float32
addParma := ¶m.AddParma{Args1: 1.2, Args2: 2.3}
err = client.Call("MathUtil.Add", addParma, &result)
if err != nil {
panic(err.Error())
}
fmt.Println("计算结果:", *result)
}
addParam.go
package param
type AddParma struct {
Args1 float32 //第一个参数
Args2 float32 //第二个参数
}
网友评论