golang实现RPC
一、RPC工作流程:
摘自《go web编程》
二、go支持三个级别的RPC( HTTP,TCP,JSONRPC)
三、实现http的RPC实例:
3.1 GO RPC的函数只有符合以下条件才能被远程访问
- 函数必须是首字母是大写
- 必须有两个首字母大写的参数
- 第一个参数是接收的参数,第二个参数是返回给客户端的参数,第二个参数必须是指针类型的
- 函数还要有一个返回值error
func (t *T)MethodName(arg1 T1, returnArg *T2)error
3.2 DEMO
3.2.1 server端
package main
import (
"errors"
"fmt"
"net/http"
"net/rpc"
)
//参数
type Args struct {
A, B int
}
//结果
type Quotient struct {
Quo int //求商
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())
}
}
3.2.2 client端
package main
import (
"fmt"
"log"
"net/rpc"
"os"
)
type Args struct {
A int
B int
}
type Quotient struct {
Quo int
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)
}
args := Args{17, 8}
var reply int
err = client.Call("Arith.Multiply", args, &reply)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Arith:%d*%d=%d\n", args.A, args.B, reply)
var quot Quotient
err = client.Call("Arith.Divide", args, ")
fmt.Printf("Arith:%d/%d=%d......%d\n", args.A, args.B, quot.Quo, quot.Rem)
}
3.3.3 启动server( go run main.go) 和 启动client( go run main.go localhost )查看运行结果