服务端
import (
"net"
"net/rpc"
"net/rpc/jsonrpc"
)
// Client->Server
type RpcObj struct {
Id int `json:"id"`
Name string `json:"name"`
}
// Server->Client
type ReplyObj struct {
Ok bool `json:"ok"`
Id int `json:"id"`
Msg string `json:"msg"`
}
// rpc处理器
type ServerHandler struct{}
// server端向client提供的方法,Client从Server端获取数据
func (serverHandler ServerHandler) GetName(id int, returnObj *RpcObj) error {
mlog.log.Informational("RPC Server rcv GetName call, id:%d", id)
returnObj.Id = id
returnObj.Name = "名称1"
return nil
}
// server端向client提供的方法,Client向Server端设置数据
func (serverHandler ServerHandler) SaveName(rpcObj RpcObj, returnObj *ReplyObj) error {
mlog.log.Informational("RPC Server rcv SaveName call, RpcObj:%s", rpcObj)
returnObj.Ok = true
returnObj.Id = rpcObj.Id
returnObj.Msg = "存储成功"
return nil
}
func StartRpcServer() {
server := rpc.NewServer()
// 开始监听,使用端口 8887
listener, err := net.Listen("tcp", ":8886")
if err != nil {
mlog.log.Error("RPC Server error %s", err)
}
defer listener.Close()
mlog.log.Informational("RPC Server Start")
// 新建处理器
serverHandler := &ServerHandler{}
// 注册处理器
server.Register(serverHandler)
// 等待并处理链接
for {
conn, err := listener.Accept()
if err != nil {
mlog.log.Error("RPC Server Accept error %s", err)
}
// 在goroutine中处理请求
// 绑定rpc的编码器,使用http connection新建一个jsonrpc编码器,并将该编码器绑定给http处理器
go server.ServeCodec(jsonrpc.NewServerCodec(conn))
}
}
Client
import (
"log"
"net"
"net/rpc/jsonrpc"
)
// 需要传输的对象
type RpcObj struct {
Id int `json:"id"`
Name string `json:"name"`
}
// 需要传输的对象
type ReplyObj struct {
Ok bool `json:"ok"`
Id int `json:"id"`
Msg string `json:"msg"`
}
func CallRpcBySynchronous() {
// 连接至服务器
client, err := net.DialTimeout("tcp", "localhost:8886", 1000*1000*1000*3) // 30秒超时时间
if err != nil {
log.Fatal("client\t-", err.Error())
}
defer client.Close()
// 建立rpc通道
clientRpc := jsonrpc.NewClient(client)
// 远程服务器返回的对象
var rpcObj RpcObj
log.Println("client\t-", "call GetName method")
// 请求数据,rpcObj对象会被填充
clientRpc.Call("ServerHandler.GetName", 1, &rpcObj)
log.Println("client\t-", "recive remote return", rpcObj)
// 远程返回的对象
var reply ReplyObj
// 传给远程服务器的对象参数
saveObj := RpcObj{2, "对象2"}
log.Println("client\t-", "call SetName method")
// 请求数据
clientRpc.Call("ServerHandler.SaveName", saveObj, &reply)
log.Println("client\t-", "recive remote return", reply)
}