联博api:着手实现一个简朴的 rpc 框架到入门 grpc (上)

admin 11个月前 (07-09) 科技 102 0

rpc 全称 Remote Procedure Call 远程过程挪用,即挪用远程方式。我们挪用当前历程中的方式时很简朴,然则想要挪用差别历程,甚至差别主机、差别语言中的方式时就需要借助 rpc 来实现,下面我一步步实现一个简朴的 rpc 挪用。

server 端注册函数,运行并吸收客户端请求

func main() {
    srv := NewServer()
    srv.Register("fn", fn)
    srv.Run()
}
//为了简朴,这里只需要吸收到新闻打印出就代表执行乐成
func fn(args ...interface{}) {
    fmt.println(args)
}

界说请求花样

type rpcData struct {
	Name string         //函数名
	Args []interface{}  //参数
}

server 运行起来后,吸收 socket 请求,剖析新闻挪用已注册的函数

//server结构体
type server struct {
	conn net.Conn                   //socket毗邻
	maps map[string]reflect.Value   //函数字典
}
//组织函数
func NewServer() *server {
	return &server{
		maps: make(map[string]reflect.Value),
	}
}
//注册函数
func (s *server) Register(fname string, fun interface{}) {
	if _, ok := s.maps[fname]; !ok {
		s.maps[fname] = reflect.ValueOf(fun)
	}
}
//运行一个socket吸收请求
func (s *server) Run() {
	listen, err := net.Listen("tcp4", ":3001")
	if err != nil {
		panic(err)
	}
	for {
		s.conn, err = listen.Accept()
		if err != nil {
			continue
		}
		go s.handleConnect()
	}
}

处置请求时,这里为了简朴我使用 json 剖析,同时需要界说一个简朴的协议:客户端发送时,前4个字节放置新闻长度,这样服务端吸收到时就能知道新闻的长度,从而正常解码新闻

func (s *server) handleConnect() {
	for {
		header := make([]byte, 4)
		if _, err := s.conn.Read(header); err != nil {
			continue
		}
		bodyLen := binary.BigEndian.Uint32(header)
		body := make([]byte, int(bodyLen))
		if _, err := s.conn.Read(body); err != nil {
			continue
		}
		var req rpcData
		if err := json.Unmarshal(body, &req); err != nil {
			continue
		}
		inArgs := make([]reflect.Value, len(req.Args))
		for i := range req.Args {
			inArgs[i] = reflect.ValueOf(req.Args[i])
		}
		fn := s.maps[req.Name]
		fn.Call(inArgs)
	}
}

client 端只需挪用函数,通过网络发送请求

func main() {
    var req = rpcData{"fn", []interface{}{1, "aaa"}}
    rpcCall(req)
}

func rpcCall(data rpcData) {
	conn, err := net.Dial("tcp4", "127.0.0.1:3001")
	if err != nil {
		panic(err)
	}
	req, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}
	buf := make([]byte, 4+len(req))
	binary.BigEndian.PutUint32(buf[:4], uint32(len(req)))
	copy(buf[4:], req)
	_, err = conn.Write(buf)
	if err != nil {
		panic(err)
	}
}

测试时,首先运行 server,然后运行 client,只要看到准确的打印就代表挪用乐成,这就是一个最简朴(简陋)的 rpc 了。

当我们使用 grpc 这些 rpc 框架时,就可以不用自己实现新闻编码解码、socket毗邻这些细节,专注于营业逻辑,而且更为可靠。

参考: https://github.com/ankur-anand/simple-go-rpc

,

联博开奖网

www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。

allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:联博api:着手实现一个简朴的 rpc 框架到入门 grpc (上)

网友评论

  • (*)

最新评论

标签列表

    文章归档

      站点信息

      • 文章总数:1175
      • 页面总数:0
      • 分类总数:8
      • 标签总数:1299
      • 评论总数:1114
      • 浏览总数:98156