0%

Go net包之RPC

net 包中关于 rpc 的简单应用

rpc 包介绍

Package rpc provides access to the exported methods of an object across a network or other I/O connection. A server registers an object, making it visible as a service with the name of the type of the object. After registration, exported methods of the object will be accessible remotely. A server may register multiple objects (services) of different types but it is an error to register multiple objects of the same type.

rpc规则:

  • 方法有且只有两个可序列化参数,且第二个参数必须是指针,作为方法的返回结果
  • 方法返回一个 error
  • 上述的所有类型、方法、字段都是公开的 ( exported )

方法示例

func (t *T) MethodName(argType T1, replyType *T2) error {}

rpc 示例

rpc 服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
type Req struct {
NumOne, NumTwo int
}

type Res struct {
Num int
}

type Server struct {}

func (s *Server) Add(req Req, res *Res) error {
res.Num = req.NumOne + req.NumTwo
time.Sleep(3*time.Second)
return nil
}

func main() {
rpc.Register(new(Server))
rpc.HandleHTTP()
listener, err := net.Listen("tcp", ":8888")
if err != nil {
log.Fatalln("listen error: ", err)
}
http.Serve(listener, nil)
}

rpc 客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
type Req struct {
NumOne, NumTwo int
}

type Res struct {
Num int
}

func main() {
client, err := rpc.DialHTTP("tcp", ":8888")
if err != nil {
log.Fatalln("dial error: ", err)
}
req := Req{1,2}
var res Res
// Synchronous call
//client.Call("Server.Add", req, &res)
//fmt.Println(res)

// Asynchronous call
addCall := client.Go("Server.Add", req, &res, nil)
LOOP: for {
select {
case <-addCall.Done:
break LOOP
default:
time.Sleep(1*time.Second)
fmt.Println("waiting...")
}
}
fmt.Println(res)
}