# 数据流程分析 - 当前实现状态 ## 问题解答 ### 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) ``` **当前实际实现:** ```go 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 方法(绕过自动编码) ```go // 手动构建完整的协议帧 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:在协议编码后追加数据 ```go 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:自定义协议实现 ```go // 实现自定义协议,在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:** ```go // 在协议编码之前写入 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:** 添加`WriteHeader`、`WriteBeforeProtocol`、`WriteAfterProtocol`等方法 3. **支持解码后的请求数据:** 添加`DecodedRequest()`方法,返回解码后的Go对象