golang rpc usage

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

# golang rpc usage ## 引言 这个文章不对RPC的底层实现做深入剖析,也不讲解RPC是什么~~ ## sample RPC三步走,方法模型、服务端搭建、客户端设计 ### model 我们以设计一个做加法运算的方法为例子 ``` type Math int //Math类 type Args struct { Ops1 int Ops2 int } func (m *Math) Add(args Args, reply *int) error { log.Print("server call Add") *reply = args.Ops1 + args.Ops1 return nil } ``` ### server ``` func main() { //创建对象 math := new(Math) //rpc服务注册了一个Math对象 公开方法供客户端调用 _ = rpc.Register(math) //指定rpc的传输协议 这里采用http协议作为rpc调用的载体 也可以用rpc.ServeConn处理单个连接请求 rpc.HandleHTTP() l, e := net.Listen("tcp", ":8080") if e != nil { log.Fatal("listen error", e) } go http.Serve(l, nil) _, _ = os.Stdin.Read(make([]byte, 1))//blocked } ``` 以上就是server的设计。 ### client ``` //为了更规范编码,采用OOP思想进行封装 type MathCaller struct { client *rpc.Client Math//for overridge } //内置客户端 func NewHttpMathCaller(addr string) *MathCaller { //调用rpc服务端提供的方法之前,先与rpc服务端建立连接 client, err := rpc.DialHTTP("tcp", addr) if err != nil { log.Fatal("dialHttp error", err) return nil } mc := new(MathCaller) mc.client = client return mc } //同步调用 func (mc *MathCaller) Add(args Args, reply *int) error { return mc.client.Call("Math.Add", args, reply)//通过这种方式,调用的时候,就类似于本地 } ``` ### client main ``` func main(){ //调用rpc服务端提供的方法之前,先与rpc服务端建立连接 mc := rpcs.NewHttpMathCaller("127.0.0.1:8080") //同步调用服务端提供的方法 args := &rpcs.Args{Ops1: 7, Ops2: 9} var reply int _ = mc.Add(*args, &reply)//调用封装后的RPC,看起来更像是调用本地的mathcaller的Add方法。 } ``` ## 总结 以上的RPC sample只适用于golang的C/S之间的调用,因为底层使用了gob编码,并非是一种通用化编码,因此,如果要在golang与其它语言一块使用rpc,那么,可以使用gRPC+protubuf。或者是使用sonrpc这种基于json协议的RPC调用。 ## Jsonrpc 基于jsonrpc,补充一个简单的demo. ``` func JsonRpcServer() error { lis, err := net.Listen("tcp", ":1234") if err != nil { return err } defer lis.Close() srv := rpc.NewServer() //注册rpc对象 if err := srv.RegisterName("Math", new(Math)); err != nil { return err } for { conn, err := lis.Accept() if err != nil { log.Fatalf("lis.Accept(): %v\n", err) } go srv.ServeCodec(jsonrpc.NewServerCodec(conn)) } } ``` ``` func JsonClientRpc() { client, err := jsonrpc.Dial("tcp", "127.0.0.1:1234") //tcp if err != nil { log.Fatal("dialing:", err) } args := &Args{Ops1: 7, Ops2: 9} var reply int err = client.Call("Math.Add", args, &reply) if err != nil { log.Fatal("rpc Math.xx err:", err) } fmt.Println("remote return:", reply) } ```

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

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

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