Go RPC

wowzai · · 8599 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


什么是RPC?

RPC是Remote Procedure Call的缩写,从字面意思理解就是远程过程调用,具体可以见维基百科的解释,如果你英文足够好可以看这里wikipedia,我的理解可以简单的用一句话来描述:RPC就是一个本地程序可以通过网络调用远程的一个子程序。


Go RPC

Go的RPC中如果客户端是Go语言编写的则将用Go特有的Gob序列化,同时可以选择rpc/jsonrpc包来用json格式序列化以便和其他的RPC System交互。

Go中的RPC有以下几个限制:

1.Remote Procedure必须是公共的,对于Go的话函数首字母必须大写。

2.Remote Procedure必须又且仅有两个参数,第一个参数是一个指向从客户端接受的数据指针,第二个参数是一个指向返回给客户端数据的指针。

3.返回值是一个error

例如,如下函数是正确的:

func F(&t1,&2) error


在rpc的Server端,我们需要通过Register方法为一个接口完成“注册”,“注册”完成之后客户端就可以通过这个接口的方法调用远程过程(Remote Procedure),例如:rpc.Register(obj)


一个例子:


ArithServer:

package main

import (
  "fmt"
  "net/rpc"
  "errors"
  "net/http"
)

type Args struct {
  A,B int
}

type Quotient struct {
  Quo,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())
  }
}


ArithClient:

package main

import (
  "net/rpc"
  "fmt"
  "log"
  "os"
)

type Args struct {
  A,B int
}

type Quotient struct {
  Quo,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)
  }
  
  // Synchronous call
  args := Args{17,8}
  var reply int
  //远程调用,args是传给远程函数的参数,reply用来接收函数的结果
  err = client.Call("Arith.Multiply",args,&reply)
  if err != nil {
    log.Fatal("arith error:",err)
  }
  fmt.Printf("Arith: %d*%d=%d\n",args.A,args.B,reply)

  var quot Quotient
  //远程调用,args是传给远程函数的参数,reply用来接收函数的结果
  err = client.Call("Arith.Divide",args,")
  if err != nil {
    log.Fatal("arith error:",err)
  }
  fmt.Printf("Arith: %d/%d=%d remainder %d\n",args.A,args.B,quot.Quo,quot.Rem)
}


开启服务端后再运行客户端:

go run ArithClient  localhost

结果:

Arith: 17*8=136

Arith: 17/8=2 remainder 1




有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:wowzai

查看原文:Go RPC

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

8599 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传