• go语言net包rpc远程调用的使用


    一、基于http的RPC

    服务端:

    package main;
    
    import (
    	"net/rpc"
    	"net/http"
    	"log"
    )
    
    //go对RPC的支持,支持三个级别:TCP、HTTP、JSONRPC
    //go的RPC只支持GO开发的服务器与客户端之间的交互,因为采用了gob编码
    
    //注意字段必须是导出
    type Params struct {
    	Width, Height int;
    }
    
    type Rect struct{}
    
    //函数必须是导出的
    //必须有两个导出类型参数
    //第一个参数是接收参数
    //第二个参数是返回给客户端参数,必须是指针类型
    //函数还要有一个返回值error
    func (r *Rect) Area(p Params, ret *int) error {
    	*ret = p.Width * p.Height;
    	return nil;
    }
    
    func (r *Rect) Perimeter(p Params, ret *int) error {
    	*ret = (p.Width + p.Height) * 2;
    	return nil;
    }
    
    func main() {
    	rect := new(Rect);
    	//注册一个rect服务
    	rpc.Register(rect);
    	//把服务处理绑定到http协议上
    	rpc.HandleHTTP();
    	err := http.ListenAndServe(":8080", nil);
    	if err != nil {
    		log.Fatal(err);
    	}
    }

    客户端:

    package main;
    
    import (
    	"net/rpc"
    	"log"
    	"fmt"
    )
    
    type Params struct {
    	Width, Height int;
    }
    
    func main() {
    	//连接远程rpc服务
    	rpc, err := rpc.DialHTTP("tcp", "127.0.0.1:8080");
    	if err != nil {
    		log.Fatal(err);
    	}
    	ret := 0;
    	//调用远程方法
    	//注意第三个参数是指针类型
    	err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);
    	if err2 != nil {
    		log.Fatal(err2);
    	}
    	fmt.Println(ret);
    	err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);
    	if err3 != nil {
    		log.Fatal(err3);
    	}
    	fmt.Println(ret);
    }
    

    二、基于tcp的RPC

    服务端:

    package main;
    
    import (
    	"net"
    	"log"
    	"net/rpc"
    )
    
    //注意字段必须是导出
    type Params struct {
    	Width, Height int;
    }
    
    type Rect struct{}
    
    func (r *Rect) Area(p Params, ret *int) error {
    	*ret = p.Width * p.Height;
    	return nil;
    }
    
    func (r *Rect) Perimeter(p Params, ret *int) error {
    	*ret = (p.Width + p.Height) * 2;
    	return nil;
    }
    
    func chkError(err error) {
    	if err != nil {
    		log.Fatal(err);
    	}
    }
    
    func main() {
    	rect := new(Rect);
    	//注册rpc服务
    	rpc.Register(rect);
    	//获取tcpaddr
    	tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
    	chkError(err);
    	//监听端口
    	tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
    	chkError(err2);
    	//死循环处理连接请求
    	for {
    		conn, err3 := tcplisten.Accept();
    		if err3 != nil {
    			continue;
    		}
    		//使用goroutine单独处理rpc连接请求
    		go rpc.ServeConn(conn);
    	}
    }
    

    客户端:

    package main;
    
    import (
    	"net/rpc"
    	"fmt"
    	"log"
    )
    
    type Params struct {
    	Width, Height int;
    }
    
    func main() {
    	//连接远程rpc服务
    	//这里使用Dial,http方式使用DialHTTP,其他代码都一样
    	rpc, err := rpc.Dial("tcp", "127.0.0.1:8080");
    	if err != nil {
    		log.Fatal(err);
    	}
    	ret := 0;
    	//调用远程方法
    	//注意第三个参数是指针类型
    	err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);
    	if err2 != nil {
    		log.Fatal(err2);
    	}
    	fmt.Println(ret);
    	err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);
    	if err3 != nil {
    		log.Fatal(err3);
    	}
    	fmt.Println(ret);
    }
    

    三、JSON RPC 方式

    jsonrpc方式是数据编码采用了json,而不是gob编码。

    服务端:

    package main;
    
    import (
    	"net"
    	"log"
    	"net/rpc"
    	"net/rpc/jsonrpc"
    )
    
    //注意字段必须是导出
    type Params struct {
    	Width, Height int;
    }
    
    type Rect struct{}
    
    func (r *Rect) Area(p Params, ret *int) error {
    	*ret = p.Width * p.Height;
    	return nil;
    }
    
    func (r *Rect) Perimeter(p Params, ret *int) error {
    	*ret = (p.Width + p.Height) * 2;
    	return nil;
    }
    
    func chkError(err error) {
    	if err != nil {
    		log.Fatal(err);
    	}
    }
    
    func main() {
    	rect := new(Rect);
    	//注册rpc服务
    	rpc.Register(rect);
    	//获取tcpaddr
    	tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
    	chkError(err);
    	//监听端口
    	tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
    	chkError(err2);
    	for {
    		conn, err3 := tcplisten.Accept();
    		if err3 != nil {
    			continue;
    		}
    		//使用goroutine单独处理rpc连接请求
    		//这里使用jsonrpc进行处理
    		go jsonrpc.ServeConn(conn);
    	}
    }
    

    客户端:

    package main;
    
    import (
    	"fmt"
    	"log"
    	"net/rpc/jsonrpc"
    )
    
    type Params struct {
    	Width, Height int;
    }
    
    func main() {
    	//连接远程rpc服务
    	//这里使用jsonrpc.Dial
    	rpc, err := jsonrpc.Dial("tcp", "127.0.0.1:8080");
    	if err != nil {
    		log.Fatal(err);
    	}
    	ret := 0;
    	//调用远程方法
    	//注意第三个参数是指针类型
    	err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);
    	if err2 != nil {
    		log.Fatal(err2);
    	}
    	fmt.Println(ret);
    	err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);
    	if err3 != nil {
    		log.Fatal(err3);
    	}
    	fmt.Println(ret);
    }
    

  • 相关阅读:
    硬盘安装CentOS 6.0(超级详细图文教程)
    js获取当前URL、域名、端口号
    前端匹配表情
    记一次复杂的数据转换
    浅拷贝与深拷贝
    js统计数组中元素的重复次数(二)
    js计算数组中某个元素重复出现的个数(一)
    移动端——处理rem根字体
    js实现简单的双向绑定
    JS正则截取两个字符串之间的字符串
  • 原文地址:https://www.cnblogs.com/jkko123/p/7039675.html
Copyright © 2020-2023  润新知