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  }