golang实现RPC

发布时间 2023-04-22 21:08:40作者: 技术颜良

 

 

一、RPC工作流程:
摘自《go web编程》

二、go支持三个级别的RPC( HTTP,TCP,JSONRPC)

三、实现http的RPC实例:

3.1 GO RPC的函数只有符合以下条件才能被远程访问

  • 函数必须是首字母是大写
  • 必须有两个首字母大写的参数
  • 第一个参数是接收的参数,第二个参数是返回给客户端的参数,第二个参数必须是指针类型的
  • 函数还要有一个返回值error
    func (t *T)MethodName(arg1 T1, returnArg *T2)error

3.2 DEMO
3.2.1 server端

package main

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

//参数
type Args struct {
	A, B int
}

//结果
type Quotient struct {
	Quo int //求商
	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("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()
	err := http.ListenAndServe(":1234", nil)
	if err != nil {
		fmt.Println(err.Error())
	}
}

3.2.2 client端

package main

import (
	"fmt"
	"log"
	"net/rpc"
	"os"
)

type Args struct {
	A int
	B int
}

type Quotient struct {
	Quo int
	Rem int
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("usage:", os.Args[0], "server")
		os.Exit(1)
	}

	serverAddress := os.Args[1]
	client, err := rpc.DialHTTP("tcp", serverAddress+":1234")
	if err != nil {
		log.Fatal("dialing:", err)
	}

	args := Args{17, 8}
	var reply int
	err = client.Call("Arith.Multiply", args, &reply)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Arith:%d*%d=%d\n", args.A, args.B, reply)

	var quot Quotient
	err = client.Call("Arith.Divide", args, &quot)
	fmt.Printf("Arith:%d/%d=%d......%d\n", args.A, args.B, quot.Quo, quot.Rem)

}

3.3.3 启动server( go run main.go) 和 启动client( go run main.go localhost )查看运行结果

 
分类: golang