zoukankan      html  css  js  c++  java
  • golang rpc demo

    RPC工作流程图

    • 1.调用客户端句柄;执行传送参数
    • 2.调用本地系统内核发送网络消息
    • 3.消息传送到远程主机
    • 4.服务器句柄得到消息并取得参数
    • 5.执行远程过程
    • 6.执行的过程将结果返回服务器句柄
    • 7.服务器句柄返回结果,调用远程系统内核
    • 8.消息传回本地主机
    • 9.客户句柄由内核接收消息
    • 10.客户接收句柄返回的数据

    Go语言提供对RPC的支持:HTTP、TCP、JSPNRPC,但是在GoRPC是独一无二的,它采用了GoLang Gob编码,只能支持Go语言!

    • GoLang Gob:是Golang包自带的一个数据结构序列化的编码/解码工具。编码使用Encoder,解码使用Decoder。一种典型的应用场景就是RPC(remote procedure calls)。

    HTTP RPC Demo

    • 服务端的代码
      package main
      
      import (
          "errors"
          "fmt"
          "net/http"
          "net/rpc"
      )
      
      type Arith int 
      
      func rpcDemo() {
          arith := new(Arith)
          fmt.Println("arith===", arith)
      
          rpc.Register(arith)
          //HandleHTTP将RPC消息的HTTP处理程序注册到Debug服务器
          //DEFAUTUPCPATH和Debug调试路径上的调试处理程序。
          //仍然需要调用http.Services(),通常是在GO语句中。
          rpc.HandleHTTP()
          err := http.ListenAndServe(":1234", nil)
          if err != nil {
              fmt.Println("err=====", err.Error())
          }   
      }
      
      type Args struct {
          A, B int
      }
      
      type Quotient struct {
          Quo, Rem int
      }
      
      //函数必须是导出的(首字母大写)
      //必须有两个导出类型的参数,
      //第一个参数是接收的参数,第二个参数是返回给客户端的参数,第二个参数必须是指针类型的
      //函数还要有一个返回值error
      func (t *Arith) Multiply(args *Args, reply *int) error {
          *reply = args.A * args.B
          fmt.Println("这个方法执行了啊---嘿嘿--- Multiply ", reply)
      
          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
          fmt.Println("这个方法执行了啊---嘿嘿--- Divide quo==", quo)
      
          return nil
      }
      
      func main() {
          rpcDemo()
      }

      服务端运行:go run server.go

    • 客户端的代码
      package main
      
      import (
          "flag"
          "fmt"
          "log"
          "net/rpc"
          "strconv"
      )
      
      type ArgsTwo struct {
          A, B int 
      }
      
      type QuotientTwo struct {
          Quo, Rem int 
      }
      
      type Conf struct {
          serverAddress string
          i1            string
          i2            string
      }
      
      var conf = Conf{}
      
      func SetConfiguration() {
          flag.StringVar(&conf.serverAddress, "address", "127.0.0.1:1234", "The address of the rpc")
          flag.StringVar(&conf.i1, "i1", "100", "100")
          flag.StringVar(&conf.i2, "i2", "2", "2")
      }
      
      func main() {
          SetConfiguration()
          flag.Parse()
          fmt.Println("severAddress = ", conf.serverAddress)
      
          // DelayHTTP在指定的网络地址连接到HTTP RPC服务器
          // 在默认HTTP RPC路径上监听。
          client, err := rpc.DialHTTP("tcp", conf.serverAddress)
          if err != nil {
              log.Fatal("发生错误了 在这里地方  DialHTTP", err)
          }
      
          i1_, _ := strconv.Atoi(conf.i1)
          i2_, _ := strconv.Atoi(conf.i2)
          args := ArgsTwo{A: i1_, B: i2_}
          var reply int
      
          //调用调用命名函数,等待它完成,并返回其错误状态。
          err = client.Call("Arith.Multiply", args, &reply)
          if err != nil {
              log.Fatal("Call Multiply  发生错误了哦   arith error:", err)
          }
          fmt.Printf("Arith 乘法: %d*%d=%d
      ", args.A, args.B, reply)
      
          var quot QuotientTwo
          //调用调用命名函数,等待它完成,并返回其错误状态。
          err = client.Call("Arith.Divide", args, &quot)
          if err != nil {
              log.Fatal("arith error:", err)
          }
          fmt.Printf("Arith 除法取整数: %d/%d=%d 余数 %d
      ", args.A, args.B, quot.Quo, quot.Rem)
      }

      客户端编译:go build client.go
      客户端运行:

    • [root@wangjq rpc]# ./client 
      severAddress =  127.0.0.1:1234
      Arith 乘法: 100*2=200
      Arith 除法取整数: 100/2=50 余数 0
      [root@wangjq rpc]# 
      [root@wangjq rpc]# ./client --address 127.0.0.1:1234 -i1 200 -i2 5
      severAddress =  127.0.0.1:1234
      Arith 乘法: 200*5=1000
      Arith 除法取整数: 200/5=40 余数 0
  • 相关阅读:
    [算法][递归]求阶乘
    [数据结构]ArrayStack
    [数据结构]Graph
    [数据结构]TrieTree
    [数据结构]UnionFindSet
    [算法]在数组中找到一个局部最小位置
    在二叉树中找到一个节点的后继节点
    [算法]折纸问题
    常用下载方式的区别-BT下载、磁力链接、电驴
    纯文本-FileOutputStream的解码方式
  • 原文地址:https://www.cnblogs.com/wangjq19920210/p/11571591.html
Copyright © 2011-2022 走看看