Go RPC 库

RPC(Remote Poresedure Call)是远程方法调用的缩写。Go的RPC库可以实现通过网络或者其他I/O方式远程调用对象的方法。

服务器注册一个对象,让它作为一个以对象类型命名的服务,让这个对象导出的方法可以被远程调用。一个服务器可以注册多个不同类型的对象,但是不能注册同一类型的多个对象。

一个能够被远程调用的方法应该像下面这样:

func (t *T) MethodName(argType T1, replyType *T2) error

一个简单的例子:实现简单的kv存储,并(在同一台机器上)通过RPC调用Put和Get方法。

package main
import (
	"fmt"
	"log"
	"net"
	"net/http"
	"net/rpc"
	"sync"
	"time"
)
// RPC struct definition
type PutArgs struct {
	Key string
	Val string
}
type PutReply struct {
	Ok bool
}
type GetArgs struct {
	Key string
}
type GetReply struct {
	Val string
}
type Kv struct {
	data map[string]string
	mu sync.Mutex
}
// server
func (kv *Kv) Get(args *GetArgs, reply *GetReply) error {
	kv.mu.Lock()
	defer kv.mu.Unlock()
	reply.Val = kv.data[args.Key]
	return nil
}
func (kv *Kv) Put(args *PutArgs, reply *PutReply) error {
	kv.mu.Lock()
	defer kv.mu.Unlock()
	kv.data[args.Key] = args.Val
	reply.Ok = true
	return nil
}
func KvServer() {
	kv := new(Kv)
	kv.data = make(map[string]string)
	rpc.Register(kv)
	rpc.HandleHTTP()
	l, err := net.Listen("tcp", ":1234")
	if err != nil {
	log.Fatal("listen error: ", err)
	}
	http.Serve(l, nil)
}
// client interface
func get(key string) string {
	client, err := rpc.DialHTTP("tcp", "127.0.0.1"+":1234")
	if err != nil {
	log.Fatal("dialing:", err)
	}
	args := GetArgs{key}
	reply := GetReply{}
	e := client.Call("Kv.Get", args, &reply)
	if e != nil {
	log.Fatal("get error", e)
	}
	client.Close()
	return reply.Val
}
func put(key string, val string) bool {
	client, err := rpc.DialHTTP("tcp", "127.0.0.1"+":1234")
	if err != nil {
	log.Fatal("dialing:", err)
	}
	args := PutArgs{key, val}
	reply := PutReply{}
	e := client.Call("Kv.Put", args, &reply)
	if e != nil {
	log.Fatal("put error", e)
	}
	client.Close()
	return reply.Ok
}
// test
func main() {
	go KvServer()
	time.Sleep(time.Second) // wait for server to start
	fmt.Println(put("key1", "value1"))
	fmt.Println(put("key2", "value2"))
	fmt.Println(put("key3", "value3"))
	fmt.Println(get("key1"))
	fmt.Println(get("key2"))
	fmt.Println(get("key3"))
	fmt.Println(get("value1"))
}
作者:雪中的茶原文地址:https://www.cnblogs.com/tea-in-the-snow/p/18004123

%s 个评论

要回复文章请先登录注册