- 12. RPC;
- 12.1 创建 rpc 服务和调用;
- 12.2 JSONRPC 使用、使用 PHP 调用;
- 12.3 初步使用 Protobuf 定义自己的 RPC 服务数据;
GO 自带的 RPC 包
// 包:net/rpc
// 基于tcp,且使用 socket,所以必须创建一个socket服务端(使用tcp的方式)
lis,err := net.Listen("tcp",":8082")
// 创建一个struct,基本规则如下
// 1. 方法可导出(首字母大写)
// 2. 方法有两个参数,都是可导出类型或内建类型
// 3. 方法的第二个参数是指针类型:第一个参数是接收的参数,第二个参数是返回的参数(客户端得到的值)
// 4. 函数有error返回
type UserService struct {
}
func(this *UserService) GetUser(userid int ,username *string) error {
if userid == 101{
*username = "vip"
}else{
*username = "guest"
}
return nil
}
// 注册:
rpc.Register(new(UserService))
// 接受客户端连接
rpc.Register(new(UserService))
- 文件 /Users/go/src/com.net/myrpcserver/main.go
package main
import (
"net"
"net/rpc"
)
type UserService struct {
}
func(this *UserService) GetUserName(userid int, username *string) error {
if userid == 101 {
*username = "vip"
} else {
*username = "guest"
}
return nil
}
func main() {
lis, _ := net.Listen("tcp", ":8082")
rpc.Register(new(UserService))
for {
client, _ :=lis.Accept()
rpc.ServeConn(client)
}
}
- 文件 /Users/go/src/com.net/myclient/main.go
package main
import (
"fmt"
"net/rpc"
)
func main() {
client, _ := rpc.Dial("tcp","127.0.0.1:8082")
username := ""
err:=client.Call("UserService.GetUserName", 102, &username)
if err != nil{
fmt.Println(err)
return
}
fmt.Println(username)
}
12.2 JSONRPC 使用、使用 PHP 调用;
- 上一节,只适合 go 与 go 之间的调用(因为它数据编码使用了 go 的 gob 编码格式)
- 要想让异构系统调用,就需要使用一些通用的编码格式,譬如 JSON
使用 PHP 写个代码连接 socket
echo "$errstr ($errno)
n";
return;
}
fwrite($fp, json_encode([
'method' =>"UserService.GetUserName",
'params' =>[102],
'id' => 0,
])."n");
echo fgets($fp);
fclose($fp);
- 文件 /Users/go/src/com.net/myrpcserver/main.go
package main
import (
"net"
"net/rpc"
"net/jsonrpc"
)
type UserService struct {
}
func(this *UserService) GetUserName(userid int, username *string) error {
if userid == 101 {
*username = "vip"
} else {
*username = "guest"
}
return nil
}
func main() {
lis, _ := net.Listen("tcp", ":8082")
rpc.Register(new(UserService))
for {
client, _ :=lis.Accept()
jsonrpc.ServeConn(client) // 使用 jsonrpc 调用
}
}
- 文件 /Users/go/src/com.net/myclient/main.go
package main
import (
"fmt"
"net/rpc"
"net/jsonrpc"
)
func main() {
client, _ := jsonrpc.Dial("tcp","127.0.0.1:8082")
username := ""
err:=client.Call("UserService.GetUserName", 102, &username)
if err != nil{
fmt.Println(err)
return
}
fmt.Println(username)
}
12.3 初步使用 Protobuf 定义自己的 RPC 服务数据;


