• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    go语言net包rpc远程调用的使用示例

    rpc 包提供了一个方法来通过网络或者其他的I/O连接进入对象的外部方法. 一个server注册一个对象, 标记它成为可见对象类型名字的服务。注册后,对象的外部方法就可以远程调用了。一个server可以注册多个 不同类型的对象,但是却不可以注册多个相同类型的对象。

    只有满足这些标准的方法才会被远程调用视为可见;其他的方法都会被忽略:

    - 方法是外部可见的。
    - 方法有两个参数,参数的类型都是外部可见的。
    - 方法的第二个参数是一个指针。
    - 方法有返回类型错误

    一、基于http的RPC

    服务端:

    package main;
    
     
    
    import (
    
      "net/rpc"
    
      "net/http"
    
      "log"
    
    )
    
     
    
    //go对RPC的支持,支持三个级别:TCP、HTTP、JSONRPC
    
    //go的RPC只支持GO开发的服务器与客户端之间的交互,因为采用了gob编码
    
     
    
    //注意字段必须是导出
    
    type Params struct {
    
      Width, Height int;
    
    }
    
     
    
    type Rect struct{}
    
     
    
    //函数必须是导出的
    
    //必须有两个导出类型参数
    
    //第一个参数是接收参数
    
    //第二个参数是返回给客户端参数,必须是指针类型
    
    //函数还要有一个返回值error
    
    func (r *Rect) Area(p Params, ret *int) error {
    
      *ret = p.Width * p.Height;
    
      return nil;
    
    }
    
     
    
    func (r *Rect) Perimeter(p Params, ret *int) error {
    
      *ret = (p.Width + p.Height) * 2;
    
      return nil;
    
    }
    
     
    
    func main() {
    
      rect := new(Rect);
    
      //注册一个rect服务
    
      rpc.Register(rect);
    
      //把服务处理绑定到http协议上
    
      rpc.HandleHTTP();
    
      err := http.ListenAndServe(":8080", nil);
    
      if err != nil {
    
        log.Fatal(err);
    
      }
    
    } 
    
    

    客户端:

    package main;
    
     
    
    import (
    
      "net/rpc"
    
      "log"
    
      "fmt"
    
    )
    
     
    
    type Params struct {
    
      Width, Height int;
    
    }
    
     
    
    func main() {
    
      //连接远程rpc服务
    
      rpc, err := rpc.DialHTTP("tcp", "127.0.0.1:8080");
    
      if err != nil {
    
        log.Fatal(err);
    
      }
    
      ret := 0;
    
      //调用远程方法
    
      //注意第三个参数是指针类型
    
      err2 := rpc.Call("Rect.Area", Params{50, 100}, ret);
    
      if err2 != nil {
    
        log.Fatal(err2);
    
      }
    
      fmt.Println(ret);
    
      err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, ret);
    
      if err3 != nil {
    
        log.Fatal(err3);
    
      }
    
      fmt.Println(ret);
    
    } 
    
    

    二、基于tcp的RPC

    服务端:

    package main;
    
     
    
    import (
    
      "net"
    
      "log"
    
      "net/rpc"
    
    )
    
     
    
    //注意字段必须是导出
    
    type Params struct {
    
      Width, Height int;
    
    }
    
     
    
    type Rect struct{}
    
     
    
    func (r *Rect) Area(p Params, ret *int) error {
    
      *ret = p.Width * p.Height;
    
      return nil;
    
    }
    
     
    
    func (r *Rect) Perimeter(p Params, ret *int) error {
    
      *ret = (p.Width + p.Height) * 2;
    
      return nil;
    
    }
    
     
    
    func chkError(err error) {
    
      if err != nil {
    
        log.Fatal(err);
    
      }
    
    }
    
     
    
    func main() {
    
      rect := new(Rect);
    
      //注册rpc服务
    
      rpc.Register(rect);
    
      //获取tcpaddr
    
      tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
    
      chkError(err);
    
      //监听端口
    
      tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
    
      chkError(err2);
    
      //死循环处理连接请求
    
      for {
    
        conn, err3 := tcplisten.Accept();
    
        if err3 != nil {
    
          continue;
    
        }
    
        //使用goroutine单独处理rpc连接请求
    
        go rpc.ServeConn(conn);
    
      }
    
    } 
    
    

    客户端: 

    package main;
    
     
    
    import (
    
      "net/rpc"
    
      "fmt"
    
      "log"
    
    )
    
     
    
    type Params struct {
    
      Width, Height int;
    
    }
    
     
    
    func main() {
    
      //连接远程rpc服务
    
      //这里使用Dial,http方式使用DialHTTP,其他代码都一样
    
      rpc, err := rpc.Dial("tcp", "127.0.0.1:8080");
    
      if err != nil {
    
        log.Fatal(err);
    
      }
    
      ret := 0;
    
      //调用远程方法
    
      //注意第三个参数是指针类型
    
      err2 := rpc.Call("Rect.Area", Params{50, 100}, ret);
    
      if err2 != nil {
    
        log.Fatal(err2);
    
      }
    
      fmt.Println(ret);
    
      err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, ret);
    
      if err3 != nil {
    
        log.Fatal(err3);
    
      }
    
      fmt.Println(ret);
    
    } 
    
    

    三、JSON RPC 方式

    jsonrpc方式是数据编码采用了json,而不是gob编码。

    服务端:

    package main;
    
     
    
    import (
    
      "net"
    
      "log"
    
      "net/rpc"
    
      "net/rpc/jsonrpc"
    
    )
    
     
    
    //注意字段必须是导出
    
    type Params struct {
    
      Width, Height int;
    
    }
    
     
    
    type Rect struct{}
    
     
    
    func (r *Rect) Area(p Params, ret *int) error {
    
      *ret = p.Width * p.Height;
    
      return nil;
    
    }
    
     
    
    func (r *Rect) Perimeter(p Params, ret *int) error {
    
      *ret = (p.Width + p.Height) * 2;
    
      return nil;
    
    }
    
     
    
    func chkError(err error) {
    
      if err != nil {
    
        log.Fatal(err);
    
      }
    
    }
    
     
    
    func main() {
    
      rect := new(Rect);
    
      //注册rpc服务
    
      rpc.Register(rect);
    
      //获取tcpaddr
    
      tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
    
      chkError(err);
    
      //监听端口
    
      tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
    
      chkError(err2);
    
      for {
    
        conn, err3 := tcplisten.Accept();
    
        if err3 != nil {
    
          continue;
    
        }
    
        //使用goroutine单独处理rpc连接请求
    
        //这里使用jsonrpc进行处理
    
        go jsonrpc.ServeConn(conn);
    
      }
    
    } 
    
    

    客户端:

     package main;
    
     
    
    import (
    
      "fmt"
    
      "log"
    
      "net/rpc/jsonrpc"
    
    )
    
     
    
    type Params struct {
    
      Width, Height int;
    
    }
    
     
    
    func main() {
    
      //连接远程rpc服务
    
      //这里使用jsonrpc.Dial
    
      rpc, err := jsonrpc.Dial("tcp", "127.0.0.1:8080");
    
      if err != nil {
    
        log.Fatal(err);
    
      }
    
      ret := 0;
    
      //调用远程方法
    
      //注意第三个参数是指针类型
    
      err2 := rpc.Call("Rect.Area", Params{50, 100}, ret);
    
      if err2 != nil {
    
        log.Fatal(err2);
    
      }
    
      fmt.Println(ret);
    
      err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, ret);
    
      if err3 != nil {
    
        log.Fatal(err3);
    
      }
    
      fmt.Println(ret);
    
    } 
    
    

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    您可能感兴趣的文章:
    • golang中的net/rpc包使用概述(小结)
    • golang的序列化与反序列化的几种方式
    • Golang Gob编码(gob包的使用详解)
    上一篇:golang中的net/rpc包使用概述(小结)
    下一篇:浅谈Go语言并发机制
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    go语言net包rpc远程调用的使用示例 语言,net,包,rpc,远程,调,