# Go 语言高级

# 参考文档

# 操作数据库

# RPC

Go 语言的 RPC 规则:方法只能有两个可序列化的参数,其中第二个参数是指针类型,并且返回一个 error 类型,同时必须是公开的方法。

即:

  • 两个可序列化参数
  • 第二个参数为指针类型
  • 返回一个 error 类型
  • 公开方法

# Go 实现简单的 rpc 调用

go 简单的 rpc 实现

server 实现:

package main

import (
    "log"
    "net"
    "net/rpc"
)

type HelloService struct{}

// 这里必须要遵守 Go 的 RPC 规则
func (p *HelloService) Hello(request string, response *string) error {
    *response = "hello" + request
    return nil
}

func main() {
    // 将一个 HelloService 类型的对象注册为一个 RPC 服务
    // 在将 HelloService 对象注册为 RPC 服务时,会将该类型中满足 RPC 规则的所有方法注册为 RPC 函数
    // 所有注册的方法会放在 “HelloService” 服务空间下。
    rpc.RegisterName("HelloService", new(HelloService))

    // 然后建立唯一的一个 TCP 链接,
    listener, err := net.Listen("tcp", ":1234")
    if err != nil {
        log.Fatal("ListenTcp error:", err)
    }

    conn, err := listener.Accept()
    if err != nil {
        log.Fatal("Accept error:", err)
    }

    // 并通过这个函数在该 TCP 链接上为对方提供 RPC 服务
    rpc.ServeConn(conn)
}
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

client 实现:

package main

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

func main() {
    // 首先通过 rpc.Dial 拨号 RPC 服务
    client, err := rpc.Dial("tcp", "localhost:1234")
    if err != nil {
        log.Fatal("dialing:", err)
    }

    var reply string
    // 然后通过 client.Call 调用具体的 RPC 方法。
    // Call 方法的第一个参数是用点号连接的 RPC 服务名字与方法名字
    // 第二个和第三个参数分别是要调用的 RPC 方法的参数。
    err = client.Call("HelloService.Hello", "handsome", &reply)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(reply)
}
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

# Protobuff

Protobuff 中数据的基本单元是 message,类似与 Go 中的结构体。

message 中可以嵌套 message 或者其它基础类型的成员。

# 讨论区

由于评论过多会影响页面最下方的导航,故将评论区做默认折叠处理。

点击查看评论区内容,渴望您的宝贵建议~
Last Updated: 6/27/2023, 9:12:38 AM