一、RPC
RPC技术在架构设计上有四部分组成,分别是:客户端、客户端存根、服务端、服务端 存根。 这里提到了客户端和服务端的概念,其属于程序设计架构的一种方式,在现代的计算 机软件程序架构设计上,大方向上分为两种方向,分别是:B/S架构、C/S架构。B/S架 构指的是浏览器到服务器交互的架构方式,另外一种是在计算机上安装一个单独的应 用,称之为客户端,与服务器交互的模式。 由于在服务的调用过程中,有一方是发起调用方,另一方是提供服务方。因此,我们 把服务发起方称之为客户端,把服务提供方称之为服务端。以下是对RPC的四种角色的 解释和说明: 客户端(Client):服务调用发起方,也称为服务消费者。 客户端存根(Client Stub):该程序运行在客户端所在的计算机机器上,主要用 来存储要调用的服务器的地址,另外,该程序还负责将客户端请求远端服务器程 序的数据信息打包成数据包,通过网络发送给服务端Stub程序;其次,还要接收 服务端Stub程序发送的调用结果数据包,并解析返回给客户端。 服务端(Server):远端的计算机机器上运行的程序,其中有客户端要调用的方 法。 服务端存根(Server Stub):接收客户Stub程序通过网络发送的请求消息数据 包,并调用服务端中真正的程序功能方法,完成功能调用;其次,将服务端执行 调用的结果进行数据处理打包发送给客户端Stub程序。
二、测试代码
?服务端server
package main
import (
"math"
"net"
"net/http"
"net/rpc"
)
type MathUtil struct {
}
//AddParma 用于多参数的统一管理
type AddParma struct {
Args1 float32
Args2 float32
}
//CalculateCircleArea 对外提供服务
func (mu *MathUtil) CalculateCircleArea(req float32,resp *float32) error {
// 计算圆的面积
*resp = math.Pi * req *req
//返回类型
return nil
}
func (mu *MathUtil) AddCircleArea(addParma AddParma,resp *float32) error {
// 加法计算
*resp = addParma.Args1 + addParma.Args2;
//返回类型
return nil
}
func main() {
//初始化结构体
mathUtil := MathUtil{}
// 调用net/rpc的功能进行注册
//err := rpc.Register(&mathUtil)
//这里可以使用取别名的方式
err := rpc.RegisterName("golang", &mathUtil)
//判断结果是否正确
if err != nil {
panic(err.Error())
}
//通过HandleHTTP()把mathUtil提供的服务注册到HTTP协议上,方便调用者利用http的方式进行数据传递
rpc.HandleHTTP()
//指定端口监听
listen, err := net.Listen("tcp", ":8081")
if err != nil {
panic(err.Error())
}
//开启服务
http.Serve(listen,nil)
}
cilent客户端
package main
import (
"fmt"
"net/rpc"
)
func main() {
type AddParma struct {
Args1 float32
Args2 float32
}
//创建连接
client, err := rpc.DialHTTP("tcp", "localhost:8081")
if err != nil {
panic(err.Error())
}
//请求值
var req float32
req = 3
//返回值
var resp *float32
//MathUtil.CalculateCircleArea这个是要调用的结构体的方法
//err = client.Call("MathUtil.CalculateCircleArea", req, &resp)
parma := AddParma{
Args1: 12,
Args2: 3,
}
//使用别名进行调用方法
err = client.Call("golang.CalculateCircleArea", req, &resp)
if err != nil {
panic(err.Error())
}
fmt.Println("圆的面积为",*resp)
err = client.Call("golang.AddCircleArea", parma, &resp)
if err != nil {
panic(err.Error())
}
fmt.Println("相加的结果为:",*resp)
}
?
|