Rpc调用的函数
package rpcArith
import "errors"
type RpcArithService struct {}
type Args struct {
A, B int
}
// 第一个参数输入;第二参数输出,必须是指针类型;返回类型error
// args 代表client提供的参数,result代表要返回给调用者的计算结果
func (RpcArithService) Div(args Args, result *float64) error{
if args.B == 0 {
return errors.New("division by zero")
}
*result = float64(args.A) / float64(args.B)
return nil
}
实现Rpc Server
package main
import (
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
"study.go.com/rpc"
)
func main() {
rpc.Register(rpcArith.RpcArithService{})
// 监听客户端发来的socket连接
// 未链接的放入“未链接”的队列中,这些套接口处于 SYN_RCVD 状态。
// 已链接(已经成功三次握手)的加入到“已链接”队列中,这些套接口处于 ESTABLISHED 状态。
listener, err := net.Listen("tcp", ":1234")
if err != nil {
panic(err)
}
for {
// 从处于 established 状态的连接队列头部取出一个已经完成的连接,
// 如果这个队列没有已经完成的连接,accept()函数就会阻塞,处于等待状态
conn, err := listener.Accept()
if err != nil {
log.Printf("accept error: %v", err)
}
// 取出链接后,jsonrpc.ServeConn开始工作,他是阻塞的,所以使用goroutine
go jsonrpc.ServeConn(conn)
}
}
实现Rpc Client
package main
import (
"fmt"
"net"
"net/rpc/jsonrpc"
"study.go.com/rpc"
)
func main() {
// 请求链接(三次握手)
conn, err := net.Dial("tcp", ":1234")
if err != nil {
panic(err)
}
client := jsonrpc.NewClient(conn)
var result float64
// 远程调用函数,等待返回结果
err = client.Call("RpcArithService.Div", rpcArith.Args{10, 3}, &result)
if err != nil {
panic(nil)
}
fmt.Println(result)
}