1、RPC使用的步骤
——-服务端:
1、注册rpc服务对象,给对象绑定方法(1.定义类,2.绑定类方法)
rpc.RegisterName("服务名",回调对象)
2、创建监听器
listener,err := net.Listen()
3、建立连接
conn,err := listener.Accept()
4、将连接绑定rpc服务
rpc.ServerConn(conn)
——-客户端:
1、用rpc连接服务器。rpc.Dial()
conn,err := rpc.Dial()
2、调用远程函数。
conn.Call("服务名.方法名",传入参数,传出参数)
二、RPC相关函数
1、注册rpc服务
func (server *Server) RegisterName(name string, rcvr interface{}) error
参数1:服务名。字符串类型。
参数2:对应 rpc 对象。该对象绑定方法要满足如下条件:
1)方法必须是导出的 -- 包外可见。
2)方法必须有两个参数,都是导出类型、内建类型。
3)方法的第二个参数必须是 “指针” (传出参数)
4)方法只有一个 error 接口类型的
举例:
type World stuct{
}
如:func (this *world) Helloword(name string,resp *string) error{
}
rpc.RegisterName("服务名",new(World))
2、绑定rpc服务
func (server *Server) ServeConn(conn io.ReadWriteCloser)
conn:成功建立好连接的 socket -- conn
3、调用远程函数
func (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) error
serviceMethod:服务名.方法名
args:传入参数。方法需要的数据
reply:传出参数。定义 var 变量,&变量名 完成参数。
4、小案例
1.服务端
package main
import (
"fmt"
"net"
"net/rpc"
)
// World 定义类对象
type World struct {
}
// HelloWorld 绑定类方法,方法名为HelloWorld
func (this *World) HelloWorld(name string, resp *string) error {
*resp = name + "您好!"
return nil
}
func main() {
//1.注册rpc服务,绑定方法,服务名为hello
err:=rpc.RegisterName("hello",new(World))
if err!=nil{
fmt.Println("注册rpc服务失败!,",err)
return
}
//2.设置监听
listener,err:=net.Listen("tcp","127.0.0.1:8800")
if err!=nil{
fmt.Println("net.Listen err:",err)
return
}
defer listener.Close()
fmt.Println("开始监听 ...")
//3.建立连接
conn,err:=listener.Accept()
if err!=nil{
fmt.Println("listener.Accept err:",err)
return
}
defer conn.Close()
fmt.Println("连接成功 ...")
//4.绑定服务
rpc.ServeConn(conn)
}
2.客户端
package main
import (
"fmt"
"net/rpc"
)
func main() {
//1.rpc连接服务器 --Dial()
conn, err := rpc.Dial("tcp", "127.0.0.1:8800")
if err != nil {
fmt.Println("rpc.Dial err:,", err)
return
}
defer conn.Close()
//2.调用远程函数
var reply string //接受函数返回值 --- 传出参数
err = conn.Call("hello.HelloWorld", "李白", &reply)
if err != nil {
fmt.Println("Call err:,", err)
return
}
fmt.Println(reply)
}
三、json版rpc
- 使用 nc -l 127.0.0.1 8800 充当服务器
- 02-client.go 充当客户端。发起通信 —- 产生乱码
- 因为:RPC使用了go语言特有的数据序列化gob。其他编程语言不能解析
- 使用通用的 序列化、反序列化。 —- json、protobuf
修改客户端,使用jsonrpc:
conn, err := jsonrpc.Dial("rcp","127.0.0.1:8800")
使用 nc -l 127.0.0.1 8800 充当服务器
看到结果:
{"method":"hello.HelloWorld","params":["李白"],"id":0}