首先,说一下目录结构:
一、HttpRPC
1、建立服务文件
/*Go RPC的函数只有符合下面的条件才能被远程访问,不然会被忽略,详细的要求如下: 函数必须是导出的(首字母大写) 必须有两个导出类型的参数, 第一个参数是接收的参数,第二个参数是返回给客户端的参数,第二个参数必须是指针类型的 函数还要有一个返回值error 举个例子,正确的RPC函数格式如下: func (t *T) MethodName(argType T1, replyType *T2) error */ package common import ( "errors" ) type Args struct { A, B float32 } type Result struct { Value float32 } type MathService struct { } func (s *MathService) Add(args *Args, result *Result) error { result.Value = args.A + args.B return nil } func (s *MathService) Divide(args *Args, result *Result) error { if args.B == 0 { return errors.New("除数不能为零!") } result.Value = args.A / args.B return nil }
2、服务端代码:
package main import ( "fmt" "net/http" "net/rpc" "../common" ) func main() { var ms = new(common.MathService) rpc.Register(ms) rpc.HandleHTTP() //将Rpc绑定到HTTP协议上。 fmt.Println("启动服务...") err := http.ListenAndServe(":1234", nil) if err != nil { fmt.Println(err.Error()) } fmt.Println("服务已停止!") }
3、客户端调用代码:
package main import ( "fmt" "net/rpc" "../common" ) func main() { var args = common.Args{17, 8} var result = common.Result{} var client, err = rpc.DialHTTP("tcp", "127.0.0.1:1234") if err != nil { fmt.Println("连接RPC服务失败:", err) } err = client.Call("MathService.Divide", args, &result) if err != nil { fmt.Println("调用失败:", err) } fmt.Println("调用结果:", result.Value) }
4、测试:
二、HttpRPC
1、建立服务文件
/*Go RPC的函数只有符合下面的条件才能被远程访问,不然会被忽略,详细的要求如下: 函数必须是导出的(首字母大写) 必须有两个导出类型的参数, 第一个参数是接收的参数,第二个参数是返回给客户端的参数,第二个参数必须是指针类型的 函数还要有一个返回值error 举个例子,正确的RPC函数格式如下: func (t *T) MethodName(argType T1, replyType *T2) error */ package common import ( "errors" ) type Args struct { A, B float32 } type Result struct { Value float32 } type MathService struct { } func (s *MathService) Add(args *Args, result *Result) error { result.Value = args.A + args.B return nil } func (s *MathService) Divide(args *Args, result *Result) error { if args.B == 0 { return errors.New("除数不能为零!") } result.Value = args.A / args.B return nil }
2、服务端文件
package main import ( "fmt" "net" "net/rpc" "../common" ) func main() { var ms = new(common.MathService) //实例化服务对像 rpc.Register(ms) //注册这个服务 fmt.Println("启动服务...") var address, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:1234") //定义TCP的服务承载地址 listener, err := net.ListenTCP("tcp", address) //监听TCP连接 if err != nil { fmt.Println("启动失败!", err) } for { conn, err := listener.Accept() //如果接受到连接 if err != nil { continue } fmt.Println("接收到一个调用请求...") rpc.ServeConn(conn) //让此rpc绑定到该Tcp连接上。 } //fmt.Println("服务已停止!") }
3、客户端代码:
// main.go package main import ( "fmt" "net/rpc" "../common" ) func main() { var client, err = rpc.Dial("tcp", "127.0.0.1:1234") if err != nil { fmt.Println("连接不到服务器:", err) } var args = common.Args{40, 3} var result = common.Result{} fmt.Println("开始调用!") err = client.Call("MathService.Add", args, &result) if err != nil { fmt.Println("调用失败!", err) } fmt.Println("调用成功!结果:", result.Value) }
4、效果: