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
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)
结论: ✅ 写数据流程是正确的!
流程是:
- Go对象(struct/map等)
- 编解码器编码(codec.Encode)→ 字节数组
- 协议编码(protocol.Encode,可选)→ 包含协议帧头的字节数组
- 写入连接(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之前写入呢?该怎么办?
当前限制:
- 协议编码是自动的: 如果启用
EnableProtocolEncode,协议编码会自动在WriteAny中执行,无法手动控制 - 无法在协议帧头之前写入数据: 当前没有API支持在协议编码之前或之后写入额外的自定义数据
- 无法自定义协议帧头格式: 协议帧头格式由协议实现决定(如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
当前实现总结
✅ 已实现
- 写数据编码: codec encode → protocol encode (可选)
- 自动编解码器匹配: 根据配置自动选择编解码器
- 协议层编码: 支持协议层编码(如nnet协议)
❌ 未实现
- 读数据解码: 没有protocol decode和codec decode
- 自定义协议帧头: 无法灵活控制协议帧头的写入
- 解码后的请求数据: 处理器无法直接获取解码后的Go对象
建议
- 实现读数据解码: 在
OnTraffic或路由匹配之前,先进行protocol decode和codec decode - 增强Context API: 添加
WriteHeader、WriteBeforeProtocol、WriteAfterProtocol等方法 - 支持解码后的请求数据: 添加
DecodedRequest()方法,返回解码后的Go对象