当前位置: 首页 > 工具软件 > jsonrpc > 使用案例 >

golang jsonrpc

宰父单弓
2023-12-01

//手动抄写一遍,

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


 类似资料:

相关阅读

相关文章

相关问答