go http rpc

1 服务端

package main
import (
    "errors"
    "fmt"
    "net/http"
    "net/rpc"
)
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("除数不能为0")
    }
    quo.Quo = args.A / args.B
    quo.Rem = args.A % args.B
    return nil
}
// 注册了一个Arith的RPC服务,
func main() {
    arith := new(Arith)
    rpc.Register(arith)
    // 把该服务注册到HTTP协议上,
    rpc.HandleHTTP()
    err := http.ListenAndServe(":1234", nil)
    if err != nil {
        fmt.Println(err.Error())
    }
}
View Code

2 客户端

package main
import (
    "fmt"
    "log"
    "net/rpc"
    "os"
)
type Args struct {
    A,B int
}
type Quotient struct {
    Quo, Rem int
}
func main()  {
    fmt.Println(os.Args)
    if len(os.Args) != 2{
        fmt.Println("用法:", os.Args[0], "server")
        // Exit 函数可以让当前程序以给出的状态码 code 退出。一般来说,状态码 0 表示成功,
        // 非 0 表示出错。程序会立刻终止,并且 defer 的函数不会被执行。
        os.Exit(1)
    }
    // 服务器地址
    serverAddress := os.Args[1]
    // 指定通信协议是tcp,并且指定IP地址和端口号,
    client, err := rpc.DialHTTP("tcp", serverAddress+":1234")
    if err != nil{
        log.Fatalf("Dial错误",)
    }
    // Synchronous call
    args := Args{17, 8}
    var reply int
    // 第一个参数是要具体调用的函数的名称,Arith是服务端注册的服务名,
    // 第二个参数是要传递给服务端的参数,
    // 第三个参数是要服务端返回的结果,注意是指针类型,
    err = client.Call("Arith.Multiply", args, &reply)
    if err != nil{
        log.Fatal("arith错误:", err)
    }
    fmt.Printf("Arith: %d*%d=%d
", args.A, args.B, reply)
    var quot Quotient
    err = client.Call("Arith.Divide", args, &quot)
    if err != nil{
        log.Fatal("arith错误:", err)
    }
    fmt.Printf("Arith: %d/%d=%d 余 %d
", args.A, args.B, quot.Quo, quot.Rem)
}
View Code

客户端的Call输入三个参数,服务端返回两个参数,

原文地址:https://www.cnblogs.com/xxswkl/p/14868914.html