golang jsonrpc

//手動抄寫一遍,

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)
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章