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)

}
posted @ 2020-04-04 23:53  ZhiChao&  阅读(338)  评论(0编辑  收藏  举报