github.com/rolandhe/saber@v0.0.4/nfour/rpc/client.go (about) 1 // rpc abstraction basing nfour 2 // Copyright 2023 The saber Authors. All rights reserved. 3 4 package rpc 5 6 import ( 7 "github.com/rolandhe/saber/nfour/duplex" 8 ) 9 10 // Client 描述rpc的客户端 11 type Client[REQ any, RES any] struct { 12 codec ClientCodec[REQ, RES] 13 trans *duplex.Trans 14 } 15 16 // NewClient 构建rpc 客户端 17 // 18 // codec 请求编解码,可以把一个struct对象 编码成二进制,也可以把二进制解码成对象 19 func NewClient[REQ any, RES any](codec ClientCodec[REQ, RES], cli *duplex.Trans) *Client[REQ, RES] { 20 return &Client[REQ, RES]{ 21 codec: codec, 22 trans: cli, 23 } 24 } 25 26 // ClientCodec 抽象数据的编解码,完成struct对象与二进制的转换 27 type ClientCodec[REQ any, RES any] interface { 28 // Decode 二进制数据解码成对象 29 Decode(payload []byte) (*RES, error) 30 // Encode 对象编码成二进制 31 Encode(req *REQ) ([]byte, error) 32 } 33 34 // SendRequest 发送业务对象请求并返回业务对象类型的响应值,底层通过编解码转成二进制后通过tcp发送 35 // 36 // req 业务对象类型的请求 37 // 38 // reqTimeout 超时配置 39 func (c *Client[REQ, RES]) SendRequest(req *REQ, reqTimeout *duplex.ReqTimeout) (*RES, error) { 40 payload, err := c.codec.Encode(req) 41 if err != nil { 42 return nil, err 43 } 44 resBuff, err := c.trans.SendPayload(payload, reqTimeout) 45 if err != nil { 46 return nil, err 47 } 48 res, err := c.codec.Decode(resBuff) 49 if err != nil { 50 return nil, err 51 } 52 return res, nil 53 } 54 55 // Shutdown 关闭客户端,底层的Trans及连接资源会被释放 56 // source 关闭客户端的场景,会输出到日志,方便排除问题 57 func (c *Client[REQ, RES]) Shutdown(source string) { 58 c.trans.Shutdown(source) 59 }