RPC remote procedure call,远程过程调用。
go语言对RPC的支持有以下要求:
1.以对象形式注册RPC
2.RPC函数必须是对象的公共函数。public,也就是首字母大写的函数
3.RPC函数必须有2个参数,类型为公共类型,或go内嵌类型。
4.RPC函数第2个参数作为返回值,必须是指针类型。
5.RPC函数必须返回一个error类型的值。
func (this *T) MethodName(args T1,reply *T2) error
默认以gob经行数据编码与解码。
TCP连接
/** * Created by Administrator on 13-12-31. */ package main import ( "errors" "net/rpc" "net" "fmt" "os" ) type Args struct { I , J int } type MyMethod int func (this *MyMethod) Mult(args *Args, reply *int) error { if args == nil || reply == nil { return errors.New("nil paramters !") } *reply = args.I*args.J return nil } type DivResult struct { Quo, Rem int } func (this *MyMethod) Div(args *Args, reply *DivResult) error{ if args == nil || reply == nil { return errors.New("nil paramters !") } if args.J == 0 { return errors.New("/0 !") } reply.Quo = args.I / args.J reply.Rem = args.I % args.J return nil } func main() { mm := new(MyMethod) server := rpc.NewServer() server.Register(mm) listener, err := net.Listen("tcp",":7777") defer listener.Close() if err != nil { fmt.Fprintf(os.Stderr, "error %s\n", err.Error()) return } server.Accept(listener) }
/**
* Created by Administrator on 13-12-31.
*/
package main
import (
"net/rpc"
"fmt"
"os"
)
type Args struct {
I , J int
}
type MyMethod int
//func (this *MyMethod) Mult(args *Args, reply *int) error {
// if args == nil || reply == nil {
// return errors.New("nil paramters !")
// }
// *reply = args.I*args.J
// return nil
//}
type DivResult struct {
Quo, Rem int
}
//func (this *MyMethod) Div(args *Args, reply *DivResult) {
// reply.Quo = args.I / args.J
// reply.Rem = args.J % args.J
//}
func main() {
pClient, err := rpc.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Fprintf(os.Stderr, "err : %s\n", err.Error())
return
}
defer pClient.Close()
// 同步RPC
var multResult int
err = pClient.Call("MyMethod.Mult", &Args{2, 7}, &multResult)
if err != nil {
fmt.Fprintf(os.Stderr, "err : %s\n", err.Error())
return
}
fmt.Fprintf(os.Stdout, "multResult = %d\n", multResult)
// 异步RPC
var divResult DivResult
pCall := pClient.Go("MyMethod.Div", &Args{5, 2}, &divResult, nil)
if pCall != nil {
fmt.Fprintf(os.Stderr, "pCall : %v %v\n", pCall, pCall.Reply)
if replyCall, ok := <-pCall.Done; ok {
fmt.Fprintf(os.Stderr, "replyCall : %v %v\n", replyCall, replyCall.Reply)
}
}
}
有疑问加站长微信联系(非本文作者)