什么是RPC?
RPC是Remote Procedure Call的缩写,从字面意思理解就是远程过程调用,具体可以见维基百科的解释,如果你英文足够好可以看这里wikipedia,我的理解可以简单的用一句话来描述:RPC就是一个本地程序可以通过网络调用远程的一个子程序。
Go RPC
Go的RPC中如果客户端是Go语言编写的则将用Go特有的Gob序列化,同时可以选择rpc/jsonrpc包来用json格式序列化以便和其他的RPC System交互。
Go中的RPC有以下几个限制:
1.Remote Procedure必须是公共的,对于Go的话函数首字母必须大写。
2.Remote Procedure必须又且仅有两个参数,第一个参数是一个指向从客户端接受的数据指针,第二个参数是一个指向返回给客户端数据的指针。
3.返回值是一个error
例如,如下函数是正确的:
func F(&t1,&2) error
在rpc的Server端,我们需要通过Register方法为一个接口完成“注册”,“注册”完成之后客户端就可以通过这个接口的方法调用远程过程(Remote Procedure),例如:rpc.Register(obj)
一个例子:
ArithServer:
package main import ( "fmt" "net/rpc" "errors" "net/http" ) type Args struct { A,B int } type Quotient struct { Quo,Rem int } type Arith int // 需要远程调用的方法 func (t *Arith) Multiply(args *Args, reply *int) error { *reply = args.A * args.B return nil } // 需要远程调用的方法 func (t *Arith) Divide(args *Args,quo *Quotient) error { if args.B == 0 { return errors.New("divide by zero") } quo.Quo = args.A / args.B quo.Rem = args.A % args.B return nil } func main() { arith := new(Arith) // 注册 rpc.Register(arith) rpc.HandleHTTP() err := http.ListenAndServe(":1234",nil) if err != nil { fmt.Println(err.Error()) } }
ArithClient:
package main import ( "net/rpc" "fmt" "log" "os" ) type Args struct { A,B int } type Quotient struct { Quo,Rem int } func main() { if len(os.Args) != 2 { fmt.Println("Usage: ",os.Args[0],"server") os.Exit(1) } serverAddress := os.Args[1] client,err := rpc.DialHTTP("tcp", serverAddress+":1234") if err != nil { log.Fatal("dialing:",err) } // Synchronous call args := Args{17,8} var reply int //远程调用,args是传给远程函数的参数,reply用来接收函数的结果 err = client.Call("Arith.Multiply",args,&reply) if err != nil { log.Fatal("arith error:",err) } fmt.Printf("Arith: %d*%d=%d\n",args.A,args.B,reply) var quot Quotient //远程调用,args是传给远程函数的参数,reply用来接收函数的结果 err = client.Call("Arith.Divide",args,") if err != nil { log.Fatal("arith error:",err) } fmt.Printf("Arith: %d/%d=%d remainder %d\n",args.A,args.B,quot.Quo,quot.Rem) }
开启服务端后再运行客户端:
go run ArithClient localhost
结果:
Arith: 17*8=136
Arith: 17/8=2 remainder 1
有疑问加站长微信联系(非本文作者)