go rpc

Posted 数据库备忘录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go rpc相关的知识,希望对你有一定的参考价值。

1. code

1.1 data.go

data.go 定义了rpc函数set、get的输入和输出的数据类型

package data


const (

      OK       = "OK"

      ErrNoKey = "ErrNoKey"

)


type Err string


type PutArgs struct {

      Key   string

      Value string

}


type PutReply struct {

      Err Err

}


type GetArgs struct {

      Key string

}


type GetReply struct {

      Err   Err

      Value string

}

1.2 server.go

定义了kv结构,并注册到rpc端口

package main


import (

      "fmt"

      "log"

      "net"

      "net/rpc"

      "sync"

      "./data"

)




type KV struct {

      mu   sync.Mutex

      data map[string]string

}


func (kv *KV) Get(args *data.GetArgs, reply *data.GetReply) error {

      kv.mu.Lock()

      defer kv.mu.Unlock()


      val, ok := kv.data[args.Key]

      if ok {

            reply.Err = data.OK

            reply.Value = val

      } else {

            reply.Err = data.ErrNoKey

            reply.Value = ""

      }

      fmt.Printf("get(%s)=%s\n",args.Key,val)

      return nil

}


func (kv *KV) Put(args *data.PutArgs, reply *data.PutReply) error {

      kv.mu.Lock()

      defer kv.mu.Unlock()


      kv.data[args.Key] = args.Value

      reply.Err = data.OK

      fmt.Printf("put(%s,%s)\n",args.Key,args.Value)

      return nil

}


func main() {

      var kv KV

      kv.data = map[string]string{}

      rpcs := rpc.NewServer()

      rpcs.Register(&kv)

      l, e := net.Listen("tcp", ":1234")

      if e != nil {

            log.Fatal("listen error:", e)

      }


      for {

            conn, err := l.Accept()

            if err == nil {

                  go rpcs.ServeConn(conn)

            } else {

                  break

            }

      }

}


1.3 client.go

client端远程可以调用server端的函数

package main


import (

      "fmt"

      "log"

      "net/rpc"

      "./data"

)




func connect() *rpc.Client {

      client, err := rpc.Dial("tcp", ":1234")

      if err != nil {

            log.Fatal("dialing:", err)

      }

      return client

}


func get(key string) string {

      client := connect()

      args := data.GetArgs{"subject"}

      reply := data.GetReply{}

      err := client.Call("KV.Get", &args, &reply)

      if err != nil {

            log.Fatal("error:", err)

      }

      client.Close()

      return reply.Value

}


func put(key string, val string) {

      client := connect()

      args := data.PutArgs{"subject", "6.824"}

      reply := data.PutReply{}

      err := client.Call("KV.Put", &args, &reply)

      if err != nil {

            log.Fatal("error:", err)

      }

      client.Close()

}




func main() {

      put("subject", "6.824")

      fmt.Printf("Put(subject, 6.824) done\n")

      fmt.Printf("get(subject) -> %s\n", get("subject"))

}



2 run

liliang@liliang-win:~/rpc$ tree

.

├── client

├── client.go

├── data

   └── data.go

├── server

└── server.go

go build server.go

go build client.go

 



以上是关于go rpc的主要内容,如果未能解决你的问题,请参考以下文章

go微服务RPC的原理与Go RPC

go微服务RPC的原理与Go RPC

[go微服务-16] Go RPC 实现服务间通信

go rpc 源码分析

Go语言_RPC_Go语言的RPC

Go微服务—— RPC