//手動抄寫一遍,
package main
import (
"fmt"
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
)
type RpcObj struct {
Id int `json:"id"` // struct標籤, 如果指定,jsonrpc包會在序列化json時,將該聚合字段命名爲指定的字符串
Name string `json:"name"`
}
// 需要傳輸的對象
type ReplyObj struct {
Ok bool `json:"ok"`
Id int `json:"id"`
Msg string `json:"msg"`
}
type ServerHandler struct{}
func (serverHandler ServerHandler) GetName(id int, returnObj *RpcObj) error {
log.Println("server\t-", "recive GetName call, id:", id)
returnObj.Id = id
returnObj.Name = "名稱1"
return nil
}
func (serverHandler ServerHandler) SaveName(rpcObj RpcObj, returnObj *ReplyObj) error {
log.Println("server\t-", "recive SaveName call, RpcObj:", rpcObj)
returnObj.Ok = true
returnObj.Id = rpcObj.Id
returnObj.Msg = "存儲成功"
return nil
}
func main() {
server := rpc.NewServer()
listener, err := net.Listen("tcp", ":8888")
if err != nil {
log.Fatal("server\t-", "listen error:", err.Error())
}
defer listener.Close()
log.Println("server\t-", "start listion on port 8888")
// 新建處理器
serverHandler := &ServerHandler{}
// 註冊處理器
server.Register(serverHandler)
// 等待並處理鏈接
go func() {
for {
conn, err := listener.Accept()
if err != nil {
log.Fatal(err.Error())
}
// 在goroutine中處理請求
// 綁定rpc的編碼器,使用http connection新建一個jsonrpc編碼器,並將該編碼器綁定給http處理器
go server.ServeCodec(jsonrpc.NewServerCodec(conn))
}
}()
//client
client, err := net.DialTimeout("tcp", "localhost:8888", 1000*1000*1000*30) // 30秒超時時間
if err != nil {
log.Fatal("client\t-", err.Error())
}
defer client.Close()
clientRpc := jsonrpc.NewClient(client)
var rpcObj RpcObj
// 請求數據,rpcObj對象會被填充
clientRpc.Call("ServerHandler.GetName", 1, &rpcObj)
// 遠程返回的對象
var reply ReplyObj
// 傳給遠程服務器的對象參數
saveObj := RpcObj{2, "對象2"}
// 請求數據
clientRpc.Call("ServerHandler.SaveName", saveObj, &reply)
fmt.Println(reply.Msg)
// Asynchronous call
divCall := clientRpc.Go("ServerHandler.SaveName", saveObj, &reply, nil)
replyCall := <-divCall.Done // will be equal to divCall
fmt.Println(replyCall.Reply)
}