• 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
    
    笃志:“博学而笃志,切问而近思,仁在其中矣。”
    弘毅:“士不可以不弘毅,任重而道远。”
    止于至善:“大学之道,在明明德,在亲民,在止于至善。”
    关注:笃志弘毅,止于至善
  • 相关阅读:
    极限编程(XP)基本原则与规范
    Displaying Alerts with UIAlertView
    Objective-C Basic
    Cocos2D Study
    DynamoDB Local for Desktop Development
    图解centos7如何关闭ipv6仅使用ipv4
    MySQL中的配置参数interactive_timeout和wait_timeout(可能导致过多sleep进程的两个参数)
    被mysql中的wait_timeout坑了
    linux:解决SSH连接Linux超时自动断开
    zookeeper-3.5.5安装报错:找不到或无法加载主类 org.apache.zookeeper.server.quorum.QuorumPeerMain
  • 原文地址:https://www.cnblogs.com/dzhy/p/11094705.html
Copyright © 2020-2023  润新知