若能与你化作星座,一起描绘星空中的梦想。|

janbar

园龄:4年5个月 粉丝:29 关注:10

2022-12-01 19:50 阅读 89 评论 0 推荐

golang的jsonrpc客户端通用写法

服务端

copy
package main import ( "errors" "fmt" "log" "net" "net/rpc" "net/rpc/jsonrpc" "os" ) // 算数运算结构体 type Arith struct { } // 算数运算请求结构体 type ArithRequest struct { A int B int } // 算数运算响应结构体 type ArithResponse struct { Pro int // 乘积 Quo int // 商 Rem int // 余数 } // 乘法运算方法 func (this *Arith) Multiply(req ArithRequest, res *ArithResponse) error { res.Pro = req.A * req.B return nil } // 除法运算方法 func (this *Arith) Divide(req ArithRequest, res *ArithResponse) error { if req.B == 0 { return errors.New("divide by zero") } res.Quo = req.A / req.B res.Rem = req.A % req.B return nil } func main() { rpc.Register(new(Arith)) // 注册rpc服务 lis, err := net.Listen("tcp", "127.0.0.1:8096") if err != nil { log.Fatalln("fatal error: ", err) } fmt.Fprintf(os.Stdout, "%s", "start connection") for { conn, err := lis.Accept() // 接收客户端连接请求 if err != nil { continue } go func(conn net.Conn) { // 并发处理客户端请求 fmt.Fprintf(os.Stdout, "%s", "new client in coming\n") jsonrpc.ServeConn(conn) }(conn) } }

go标准库客户端

copy
package main import ( "fmt" "log" "net/rpc/jsonrpc" ) // 算数运算请求结构体 type ArithRequest struct { A int B int } // 算数运算响应结构体 type ArithResponse struct { Pro int // 乘积 Quo int // 商 Rem int // 余数 } func main() { conn, err := jsonrpc.Dial("tcp", "127.0.0.1:8096") if err != nil { log.Fatalln("dailing error: ", err) } req := ArithRequest{9, 2} var res ArithResponse err = conn.Call("Arith.Multiply", req, &res) // 乘法运算 if err != nil { log.Fatalln("arith error: ", err) } fmt.Printf("%d * %d = %d\n", req.A, req.B, res.Pro) err = conn.Call("Arith.Divide", req, &res) if err != nil { log.Fatalln("arith error: ", err) } fmt.Printf("%d / %d, quo is %d, rem is %d\n", req.A, req.B, res.Quo, res.Rem) }

通用客户端

主要是下面这种方式,其他任何语言都可以使用tcp封装入参和并且解析返回数据,因为入参和返回值都可以通过json进行解析

copy
package main import ( "bytes" "encoding/json" "fmt" "io" "net" ) func main() { err := f() if err != nil { panic(err) } } func f() error { c, err := net.Dial("tcp", "127.0.0.1:8096") if err != nil { return err } defer c.Close() type clientRequest struct { Method string `json:"method"` Params [1]any `json:"params"` // 参数就是服务器结构体序列化的json Id uint64 `json:"id"` } var b bytes.Buffer err = json.NewEncoder(io.MultiWriter(c, &b)).Encode(clientRequest{ Method: "Arith.Divide", Params: [1]any{json.RawMessage(`{"A":123,"B":17}`)}, Id: 1, }) if err != nil { return err } fmt.Println("args", b.String()) var clientResponse struct { Id uint64 `json:"id"` Result *json.RawMessage `json:"result"` // 返回结果就是服务器结果结构体 Error any `json:"error"` } b.Reset() err = json.NewDecoder(io.TeeReader(c, &b)).Decode(&clientResponse) if err != nil { return err } fmt.Println("resp", b.String()) var ArithResponse struct { Pro int // 乘积 Quo int // 商 Rem int // 余数 } err = json.Unmarshal(*clientResponse.Result, &ArithResponse) if err != nil { return err } fmt.Println(ArithResponse) return nil }

可以看到结果是:

copy
args {"method":"Arith.Divide","params":[{"A":123,"B":17}],"id":1} resp {"id":1,"result":{"Pro":0,"Quo":7,"Rem":4},"error":null} {0 7 4}

因此用telnet就可以做到与服务器通信,所以客户端可以是其他任何语言,只要能收发tcp即可

image

posted @   janbar  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10亿数据,如何做迁移?
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 易语言 —— 开山篇
· Trae初体验

FAVOURITE

点击右上角即可分享
微信分享提示
*✧⁺˚⁺ପ(๑・ω・)੭ु⁾⁾ 好好学习天天向上
进入亮色模式
进入亮色模式

FAVOURITE