rpc

作者: 遇见你_17be | 来源:发表于2019-01-22 17:05 被阅读0次

import "net/rpc"

rpc包提供了通过网络或其他I/O连接对一个对象的导出方法的访问。服务端注册一个对象,使它作为一个服务被暴露,服务的名字是该对象的类型名。注册之后,对象的导出方法就可以被远程访问。服务端可以注册多个不同类型的对象(服务),但注册具有相同类型的多个对象是错误的。

服务端

package main

import (

    "errors"

    "net"

    "net/rpc"

    "log"

    "net/http"

)

type Args struct {

    A, B int

}

type Quotient struct {

    Quo, Rem int

}

// 这个类型即将用于注册rpc服务

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()  // 注册默认的http处理函数

    l, e := net.Listen("tcp", ":1234")    // 网络监听tcp

    if e != nil {

        log.Fatal("listen error:", e)

    }

    http.Serve(l, nil)  // 启动http服务器  一般会调用 go http.Serve(l,nil)另开启线程 

}

客户端

package main

import (

    "net/rpc"

    "log"

    "fmt"

)

type Args struct {

    A, B int

}

type Quotient struct {

    Quo, Rem int

}

func main()  {

    client, err := rpc.DialHTTP("tcp", "127.0.0.1:1234")  // DialHTTP在指定的网络和地址与在默认HTTP RPC路径监听的HTTP RPC服务端连接。

    if err != nil {

        log.Fatal("dialing:", err)

    }

    // Synchronous call

    args := &Args{7,8}  // 新建一个参数

    var reply int  // 保存rpc返回值

    err = client.Call("Arith.Multiply", args, &reply)  // Call调用指定的方法,等待调用返回,将结果写入reply,然后返回执行的错误状态。

    if err != nil {

        log.Fatal("arith error:", err)

    }

    fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)

    // Asynchronous call

    quotient := new(Quotient)  // 新建一个变量

    divCall := client.Go("Arith.Divide", args, quotient, nil)  // Go异步的调用函数  最后参数为nil,表示开启一个线程去执行,也可以指定一个有缓存的通道

    replyCall := <-divCall.Done // will be equal to divCall  获取返回值

    if replyCall.Error != nil {

        log.Fatal("arith error:", replyCall.Error)

    }

    fmt.Printf("Arith: %d/%d=%d...%d", args.A, args.B, quotient.Quo, quotient.Rem)

    // check errors, print, etc.

}

相关文章

网友评论

      本文标题:rpc

      本文链接:https://www.haomeiwen.com/subject/lpkrjqtx.html