Go标准包RPC的使用

服务端

package main

import (
        "errors"
        "fmt"
        "net"
        "net/rpc"
)

// rpc服务端
// 实现两个Rpc接口
// 1. 计算除数和被除数两个数的乘积,返回乘积结果
// 2. 计算除数和被除数两个数的除法结果,返回商和余数

// 请求参数结构体
type RequestParam struct {
        Dividend int // 被除数
        Divisor  int // 除数
}

// 乘积计算结果直接返回int类型

// 返回两个数的商和余数响应结构体
type DivisionResponse struct {
        Quotient  int // 商
        Remainder int // 余数
}

// 定义空结构体,用于绑定方法
type Calc struct {
}

// rpc通信中结构体结构`(request,*response) error`
// 计算乘法
func (c *Calc) Multi(req RequestParam, rsp *int) error {
        *rsp = req.Dividend * req.Divisor
        return nil
}

// 计算除法
func (c *Calc) Sub(req RequestParam, rsp *DivisionResponse) error {
        if req.Divisor == 0 {
                err := errors.New("the divisor cannot be zero")
                return err
        }

        rsp.Quotient = req.Dividend / req.Divisor
        rsp.Remainder = req.Dividend % req.Divisor
        return nil
}

func main() {
        // 注册rpc服务
        err := rpc.Register(new(Calc))
        if err != nil {
                fmt.Printf("register calc server failed, err: %v\n", err)
                return
        }
        /* 通过http方式监听rpc */
        // 设置http handle
        //rpc.HandleHTTP()

        // 启动http服务监听
        //err = http.ListenAndServe(":8080", nil)
        //if err != nil {
        //      log.Fatal("start listen failed", err)
        //}

        /* 直接通过socket方式监听rpc服务 */
        listener, err := net.Listen("tcp", ":8080")
        if err != nil {
                fmt.Printf("create tcp listen failed, err: %v\n", err)
                return
        }
        rpc.Accept(listener)
}

客户端

package main

import (
        "fmt"
        "net/rpc"
)

// rpc客户端

// 请求参数结构体
type RequestParam struct {
        Dividend int // 被除数
        Divisor  int // 除数
}

// 乘积计算结果直接返回int类型

// 返回两个数的商和余数响应结构体
type DivisionResponse struct {
        Quotient  int // 商
        Remainder int // 余数
}

func main() {
        /* 通过http方式监听rpc */
        //rpcClient, err := rpc.DialHTTP("tcp", "127.0.0.1:8080")
        /* 直接通过socket方式监听rpc服务 */
        rpcClient, err := rpc.Dial("tcp", "127.0.0.1:8080")
        if err != nil {
                fmt.Printf("connection rpc server failed, err: %v\n", err)
                return
        }
        defer rpcClient.Close()
        // 计算乘法
        var multiResult int
        err = rpcClient.Call("Calc.Multi", RequestParam{10, 3}, &multiResult)
        if err != nil {
                fmt.Printf("call Calc.Multi failed, err: %v\n", err)
        }
        fmt.Printf("乘积: %d\n", multiResult)
        var subResult DivisionResponse
        err = rpcClient.Call("Calc.Sub", RequestParam{10, 3}, &subResult)
        if err != nil {
                fmt.Printf("call Calc.Sub failed, err: %v\n", err)
        }
        fmt.Printf("商: %d, 余数: %d\n", subResult.Quotient, subResult.Remainder)

}