You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5.0 KiB

数据流程分析 - 当前实现状态

问题解答

1. 读数据流程

你期望的流程:

read bytes -> protocol decode (data bytes) -> codec decode (go struct 或其它结构)

当前实际实现:

read bytes -> SetRequest(raw bytes) -> 路由匹配 -> 处理器

问题: 当前实现中没有进行protocol decode和codec decode

数据是原始字节直接传递给处理器,没有经过任何解码。

2. 写数据流程

你期望的流程:

write any or bytes -> codec encode (bytes) -> protocol encode (bytes)

当前实际实现:

WriteAny(go struct) -> codec.Encode(data) -> protocol.Encode(encodedData) (可选) -> Write(bytes)

结论: 写数据流程是正确的!

流程是:

  1. Go对象struct/map等
  2. 编解码器编码codec.Encode→ 字节数组
  3. 协议编码protocol.Encode可选→ 包含协议帧头的字节数组
  4. 写入连接Write

3. 完整的数据流程(当前状态)

写数据流程

处理器中:
  ctx.WriteAny(struct{...}) 
    ↓
  codec.Encode(struct) → []byte (JSON/Binary/Protobuf等)
    ↓
  protocol.Encode([]byte) → []byte (包含Magic、长度、校验和等可选)
    ↓
  conn.Write([]byte) → 客户端

读数据流程 (未实现)

客户端 → conn.Read() → []byte (原始字节)
  ↓
SetRequest([]byte) → ctx.Request() (仍然是原始字节)
  ↓
路由匹配 → 处理器
  ↓
处理器中直接使用 ctx.Request() (原始字节,未解码)

问题: 读数据时没有进行:

  • protocol decode去除协议帧头
  • codec decode将字节解码为Go对象

4. 自定义协议帧头问题

你的问题:

如果我需要在 write 时写入一些自定义协议帧头数据呢或者在write之前写入呢该怎么办

当前限制:

  1. 协议编码是自动的: 如果启用EnableProtocolEncode,协议编码会自动在WriteAny中执行,无法手动控制
  2. 无法在协议帧头之前写入数据: 当前没有API支持在协议编码之前或之后写入额外的自定义数据
  3. 无法自定义协议帧头格式: 协议帧头格式由协议实现决定如nnet协议的Magic、长度、校验和无法自定义

解决方案:

方案1直接使用 Write 方法(绕过自动编码)

// 手动构建完整的协议帧
func handler(ctx ctxpkg.Context) error {
    // 1. 准备数据
    data := []byte("your data")
    
    // 2. 手动添加自定义协议帧头
    header := []byte("CUSTOM_HEADER")
    frame := append(header, data...)
    
    // 3. 直接写入绕过codec和protocol编码
    return ctx.Write(frame)
}

方案2在协议编码后追加数据

func handler(ctx ctxpkg.Context) error {
    // 1. 使用WriteAny自动编码
    resp := Response{Code: 200}
    ctx.WriteAny(resp)  // 自动进行codec encode和protocol encode
    
    // 2. 追加自定义数据
    customData := []byte("custom footer")
    ctx.Write(customData)
    
    return nil
}

方案3自定义协议实现

// 实现自定义协议在Encode方法中添加自定义帧头
type CustomProtocol struct {
    // ...
}

func (p *CustomProtocol) Encode(data []byte) ([]byte, error) {
    // 添加自定义协议帧头
    header := []byte("CUSTOM_HEADER")
    // ... 其他协议帧头字段
    return append(header, data...), nil
}

需要实现的功能

1. 读数据解码支持

需要实现:

  • protocol decode去除协议帧头提取数据部分
  • codec decode将字节解码为Go对象

建议的读数据流程:

read bytes → protocol.Decode(bytes) → data bytes → codec.Decode(data bytes) → go struct

2. 写数据增强

需要支持:

  • 在协议编码之前写入自定义数据
  • 在协议编码之后写入自定义数据
  • 自定义协议帧头格式

建议的API

// 在协议编码之前写入
ctx.WriteBeforeProtocol(data []byte) error

// 在协议编码之后写入
ctx.WriteAfterProtocol(data []byte) error

// 写入自定义协议帧头
ctx.WriteHeader(header []byte) error

当前实现总结

已实现

  1. 写数据编码: codec encode → protocol encode (可选)
  2. 自动编解码器匹配: 根据配置自动选择编解码器
  3. 协议层编码: 支持协议层编码如nnet协议

未实现

  1. 读数据解码: 没有protocol decode和codec decode
  2. 自定义协议帧头: 无法灵活控制协议帧头的写入
  3. 解码后的请求数据: 处理器无法直接获取解码后的Go对象

建议

  1. 实现读数据解码:OnTraffic或路由匹配之前先进行protocol decode和codec decode
  2. 增强Context API 添加WriteHeaderWriteBeforeProtocolWriteAfterProtocol等方法
  3. 支持解码后的请求数据: 添加DecodedRequest()方法返回解码后的Go对象