# Go 语言高级
# 参考文档
# 操作数据库
# RPC
Go 语言的 RPC 规则:方法只能有两个可序列化的参数,其中第二个参数是指针类型,并且返回一个 error 类型,同时必须是公开的方法。
即:
- 两个可序列化参数
- 第二个参数为指针类型
- 返回一个 error 类型
- 公开方法
# 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
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
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 或者其它基础类型的成员。
# 讨论区
由于评论过多会影响页面最下方的导航,故将评论区做默认折叠处理。
点击查看评论区内容,渴望您的宝贵建议~
← Go 语言基础