Go中的RPC支持与处理

在Go中net/rpc标准包提供了编写RPC服务需要的系列函数。net/rpc包允许RPC客户端通过网络或者IO连接调用一个远端对象的public方法。在RPC服务端,可将一个对象注册为可访问的服务,之后该对象的公开方法就能够被远程调用。一个RPC服务端可以注册多个不同类型的对象,但是不允许注册同一类型的多个对象。

一个对象中的方法只有满足如下条件,才能被RPC服务端设置为可远程调用:

  • 必须是在对象外部可访问的(首字母大写)
  • 必须有两个参数,且参数类型都必须是包外部可以访问的类型或者Go内置类型
  • 第二个参数必须是一个指针
  • 方法必须返回一个error类型的值

用代码表示如下:

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

在这行代码中,类型T, T1, T2默认会使用Go内置的encoding/gob包进行编码解码。该方法的第一个参数表示有RPC客户端传入的参数,第二个参数表示要返回给RPC客户端的结果,最后返回一个error类型的结果。

RPC服务端可以通过调用rpc.ServeConn处理单个连接请求,但是大多数情况下,都是通过TCP或HTTP在某个网络地址上监听来创建服务。在客户端,net/rpc包提供了rpc.Dial()和rpc.DialHTTP()方法来与指定的RPC服务器建立连接。在建立连接之后,Go的net.rpc包允许我们使用同步(rpc.Call)或者异步(rpc.Go)方式接收RPC服务端的处理结果。

Server端代码:

 1 package server
 2 
 3 import (
 4     "errors"
 5     "log"
 6     "net"
 7     "net/http"
 8     "net/rpc"
 9 )
10 
11 type Args struct {
12     A, B int
13 }
14 
15 type Quotiten struct {
16     Quo, Rem int
17 }
18 
19 type Arith int
20 
21 func (t *Arith) Multiply(args *Args, reply *int) error {
22     *reply = args.A * args.B
23     return nil
24 }
25 
26 func (t *Arith) Divide(args *Args, quo *Quotiten) error {
27     if args.B == 0 {
28         return errors.New("divide by zero")
29     }
30     quo.Quo = args.A / args.B
31     quo.Rem = args.A % args.B
32     return nil
33 }
34 
35 func init() {
36     arith := new(Arith)
37     rpc.Register(arith)
38     rpc.HandleHTTP()
39     l, e := net.Listen("tcp", ":1234")
40     if e != nil {
41         log.Fatal("listen error: ", e)
42     }
43     go http.Serve(l, nil)
44 }

客户端调用代码

 1 package main
 2 
 3 import (
 4     "./server"
 5     "fmt"
 6     "log"
 7     "net/rpc"
 8 )
 9 
10 func main() {
11     client, err := rpc.DialHTTP("tcp", "localhost:1234")
12     if nil != err {
13         log.Fatal("dialing:", err)
14     }
15 
16     args := &server.Args{7, 8}
17     var reply int
18     err = client.Call("Arith.Multiply", args, &reply)
19     if nil != err {
20         log.Fatal("arith error:", err)
21     }
22     fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
23 }

原文地址:https://www.cnblogs.com/lniwn/p/3377847.html