json、结构体标签和rpc入门

json使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main

import (
   "encoding/json"
   "fmt"
   "reflect"
)

// 将 结构体 --> 字符串  编码
// 将 字符串 --> 结构体  解码

// 结构体的成员须大写,不然不参与编码

type Student struct {
   Name  string
   Sex   string
   Age   int
   Score int
}

func main() {
   st1 := Student{
      Name:  "luenci",
      Sex:   "man",
      Age:   22,
      Score: 99,
   }
   // 编码 序列化
   encodeInfo, err := json.Marshal(st1)
   if err != nil {
      fmt.Println("序列化发生错误,error", err)
      return
   }
   fmt.Println(reflect.TypeOf(encodeInfo))
   fmt.Println(string(encodeInfo))

   // 解码 反序列化
   var st2 Student

   if err := json.Unmarshal([]byte(encodeInfo), &st2); err != nil {
      fmt.Println("反序列化发生错误,", err)
      return
   }
   fmt.Println(st2.Name)

}

结构体标签

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import (
   "encoding/json"
   "fmt"
)

// 结构体标签由一个或多个键值对组成。
// 键与值使用冒号分隔,值用双引号括起来。键值对之间使用一个空格分隔。

type Teacher struct {
   Name    string `json:"-"`                 // 在使用json编码时候,这个字段不参与编码
   Subject string `json:"subject_name"`      // 在使用json编码时候,这个字段会编码成 subject_name
   Age     int    `json:"age,string"`        // 在使用json编码时候,这个字段类型会变成age and 类型会变为 string
   Address string `json:"address,omitempty"` // 在使用json编码时候,如果这个字段是空的,就会忽略掉不编码

   // 小写的结构体成员在json编码时候会被忽略掉
   gender string
}

func main() {
   t1 := Teacher{
      Name:    "lynn",
      Subject: "math",
      Age:     0,
      Address: "123",
      gender:  "girl",
   }

   marshal, err := json.Marshal(t1)
   if err != nil {
      return
   }
   fmt.Println("编码后结果为:", string(marshal))
}

rpc封装设计

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import (
   "net/rpc"
)

type MyInterface interface {
   HelloWorld(string, *string) error
}

// 服务端注册函数
func RegisterName(i MyInterface) error {
   err := rpc.RegisterName("Hello", i)
   if err != nil {
      return err
   }
   return nil
}

type MyClient struct {
   c *rpc.Client
}

func InitClient(addr string) MyClient {
   conn, _ := rpc.Dial("tcp", addr)
   return MyClient{c: conn}
}

// 实现函数参照interface实现
func (this *MyClient) HelloWorld(name string, resp *string) error {
   return this.c.Call("Hello.HelloWorld", name, resp)
}

rpc-server

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package main

import (
   "fmt"
   "net"
   "net/rpc/jsonrpc"
)

type Hello struct {
}

func (this *Hello) HelloWorld(name string, resp *string) error {
   *resp = name + " 你好!"
   return nil
}

func main() {
   // 1.注册服务
   //if err := rpc.RegisterName("luenci", new(Hello)); err != nil {
   // fmt.Println("注册服务失败:", err)
   // return
   //}
   if err := RegisterName(new(Hello)); err != nil {
      fmt.Println("服务注册失败,error", err)
      return
   }

   // 2.设置监听着
   listenner, err := net.Listen("tcp", "127.0.0.1:8800")
   if err != nil {
      fmt.Println("设置监听者失败:", err)
      return
   }
   defer listenner.Close()

   // 3.建立链接
   conn, err := listenner.Accept()
   if err != nil {
      fmt.Println("建立链接失败:", err)
      return
   }
   defer conn.Close()

   // 4.绑定服务 jsonrpc
   //rpc.ServeConn(conn)
   jsonrpc.ServeConn(conn)
}

rpc-client(go)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main

import (
   "fmt"
   "net/rpc"
)

func main() {
   /* --------------------- 方式一 ------------------*/
   // 通用的序列化和反序列化 -- json、protobuf
   // 使用 Dail 链接服务器 -- Dail()
   //conn, err := rpc.Dial("tcp", "127.0.0.1:8800")

   //conn, err := jsonrpc.Dial("tcp", "127.0.0.1:8800")
   //if err != nil {
   // fmt.Println("Dail error:", err)
   // return
   //}
   //defer conn.Close()
   //
   //// 调用远程函数
   //var response string // 接收返回值 -- 传出参数
   //if err := conn.Call("luenci.HelloWorld", "lynn", &response); err != nil {
   // fmt.Println("Call error", err)
   // return
   //}
   //fmt.Println("response", response)

   /* --------------------- 方式二 ------------------*/

   MyClient := InitClient("127.0.0.1:8800")
   defer func(c *rpc.Client) {
      err := c.Close()
      if err != nil {
         fmt.Println("关闭链接出错.error", err)
         return
      }
   }(MyClient.c)

   var resp string
   err := MyClient.HelloWorld("luenci", &resp)
   if err != nil {
      fmt.Println("出错了,error", err)
      return
   }
}

rpc-client(python)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import json
import socket               # 导入 socket 模块

s = socket.socket()         # 创建 socket 对象
host = "127.0.0.1" # 获取本地主机名
port = 8800                # 设置端口号

s.connect((host, port))
data = json.dumps({"method":"luenci.HelloWorld","params":["lynn"],"id":0})
print(data)
s.send(data)
res = s.recv(1024)
print(res)
print(type(res))
s.close()