trpc.group/trpc-go/trpc-go@v1.0.3/docs/developer_guide/develop_plugins/protocol.zh_CN.md (about)

     1  [English](protocol.md) | 中文
     2  
     3  # 怎么开发一个 protocol 类型的插件
     4  
     5  本指南将介绍如何开发一个不依赖配置文件的 protocol 类型的插件。
     6  
     7  开发一个 protocol 类型的插件至少需要实现以下两个子功能:
     8  
     9  - 实现 `codec.Framer` 和  `codec.FramerBuilder` 接口, 从连接中读取出完整的业务包
    10  - 实现 `codec.Codec` 接口, 从完整的二进制网络数据包解析出二进制请求包体,和把二进制响应包体打包成一个完整的二进制网络数据
    11  
    12  除此之外,根据具体的 protocol,还有可能需要实现 `codec.Serializer` 和 `codec.Compressor` 接口。
    13  
    14  下面以实现 trpc-codec 中的 “rawstring” 协议为例,来介绍相关开发步骤,更具体的代码可以参考[这里](https://github.com/trpc-ecosystem/go-codec/tree/main/rawstring)。
    15  
    16  "rawstring"协议是一种简单的基于 tcp 的通信协议,其特点是以 “\n” 字符为分隔符进行收发包。
    17  
    18  ## 实现 `codec.Framer` 和  `codec.FramerBuilder` 接口
    19  
    20  ```go
    21  type FramerBuilder struct{}
    22  
    23  func (fd *FramerBuilder) New(reader io.Reader) transport.Framer {
    24      return &framer{
    25          reader: reader,
    26      }
    27  }
    28  
    29  type framer struct {
    30      reader io.Reader
    31  }
    32  
    33  func (f *framer) ReadFrame() (msg []byte, err error) {
    34      reader := bufio.NewReader(f.reader)
    35      return reader.ReadBytes('\n')
    36  }
    37  ```
    38  
    39  将实现好的 FramerBuilder 注册到 `transport` 包
    40  
    41  ```go
    42  var DefaultFramerBuilder = &FramerBuilder{}
    43  func init() {
    44      transport.RegisterFramerBuilder("rawstring", DefaultFramerBuilder)
    45  }
    46  ```
    47  
    48  ## 实现 `codec.Codec` 接口
    49  
    50  ### 实现服务端 Codec
    51  
    52  ```go
    53  type serverCodec struct{}
    54  
    55  func (sc *serverCodec) Decode(_ codec.Msg, req []byte) ([]byte, error) {
    56      return req, nil
    57  }
    58  
    59  func (sc *serverCodec) Encode(_ codec.Msg, rsp []byte) ([]byte, error) {
    60      return []byte(string(rsp) + "\n"), nil
    61  }
    62  ```
    63  
    64  ### 实现客户端 Codec
    65  
    66  ```go
    67  type clientCodec struct{}
    68  
    69  func (cc *clientCodec) Encode(_ codec.Msg, reqBody []byte) ([]byte, error) {
    70      return []byte(string(reqBody) + "\n"), nil
    71  }
    72  
    73  func (cc *clientCodec) Decode(_ codec.Msg, rspBody []byte) ([]byte, error) {
    74      return rspBody, nil
    75  }
    76  ```
    77  
    78  ### 将实现好的 Codec 注册到 `codec` 包
    79  
    80  ```go
    81  func init() {
    82  	codec.Register("rawstring", &serverCodec{}, &clientCodec{})
    83  }
    84  ```
    85  
    86  ## 更多例子
    87  
    88  更多例子可以参考 [trpc-codec 代码仓库](https://github.com/trpc-ecosystem/go-codec)