golang——net/rpc/jsonrpc包学习

1、jsonrpc包

该实现了JSON-RPC的ClientCodec和ServerCodec接口,可用于rpc包。

可用于跨语言使用go rpc服务。

2、常用方法

(1)func Dial(network, address string) (*rpc.Client, error)

Dial在指定的网络和地址连接一个JSON-RPC服务端。

(2)func NewClient(conn io.ReadWriteCloser) *rpc.Client

NewClient返回一个新的rpc.Client,以管理对连接另一端的服务的请求。

(3)func NewClientCodec(conn io.ReadWriteCloser) rpc.ClientCodec

NewClientCodec返回一个在连接上使用JSON-RPC的rpc.ClientCodec。

(4)func NewServerCodec(conn io.ReadWriteCloser) rpc.ServerCodec

NewServerCodec返回一个在连接上使用JSON-RPC的rpc. ServerCodec。

(5)func ServeConn(conn io.ReadWriteCloser)

ServeConn在单个连接上执行DefaultServer。

ServeConn会阻塞,服务该连接直到客户端挂起。

调用者一般应另开线程调用本函数:"go serveConn(conn)"。

ServeConn在该连接使用JSON编解码格式

3、代码示例

package main

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

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

// Quotient 商、余数
type Quotient struct {
	Quo, Rem int
}

// Arith 算术服务
type Arith int

// Multiply 乘法服务
func (*Arith) Multiply(args *Args, reply *int) error {
	*reply = args.A * args.B
	return nil
}

// Divide 除法服务
func (*Arith) Divide(args *Args, quo *Quotient) error {
	if args.B == 0 {
		return errors.New("除数不能为零")
	}
	quo.Quo = args.A / args.B
	quo.Rem = args.A % args.B
	return nil
}

// 错误检查
func checkErr(err error) {
	if err != nil {
		log.Fatalln(err)
	}
}
func main() {
	//注册服务
	err := rpc.Register(new(Arith))
	checkErr(err)
	//设置监听
	lis, err := net.Listen("tcp", "127.0.0.1:1234")
	checkErr(err)
	//服务端等待请求
	go func(lis net.Listener) {
		for {
			conn, err := lis.Accept()
			if err != nil {
				continue
			}
			// 并发处理客户端请求
			go func(conn net.Conn) {
				jsonrpc.ServeConn(conn)
			}(conn)
		}
	}(lis)
	//客户端请求服务
	client, err := jsonrpc.Dial("tcp", ":1234")
	checkErr(err)
	defer client.Close()
	//乘法
	args := &Args{A: 17, B: 3}
	var reply int
	err = client.Call("Arith.Multiply", args, &reply)
	checkErr(err)
	fmt.Printf("Arith.Multiply:%d * %d = %d
", args.A, args.B, reply)
	//除法
	quotient := new(Quotient)
	call := client.Go("Arith.Divide", args, quotient, nil)
	<-call.Done
	fmt.Printf("Arith.Divide:%d / %d = %d .... %d
", args.A, args.B, quotient.Quo, quotient.Rem)
}

//输出
// Arith.Multiply:17 * 3 = 51
// Arith.Divide:17 / 3 = 5 .... 2
笃志:“博学而笃志,切问而近思,仁在其中矣。”
弘毅:“士不可以不弘毅,任重而道远。”
止于至善:“大学之道,在明明德,在亲民,在止于至善。”
关注:笃志弘毅,止于至善
原文地址:https://www.cnblogs.com/dzhy/p/11094705.html