Files
4566704 9d7a512e18 feat(frame): go-hua/common 帧协议独立成包并修复两处缺陷
- SetData 超长时 fmt.Errorf 结果未 return,超 65535 字节静默放行 → 改为返回错误
- ReadFrame 原实现 conn.Read 直读帧头(短读错位)且一次性 bufio.Reader 会丢弃
  缓冲中的后续帧字节 → 统一改 io.ReadFull 精确读取,新增连续两帧回归测试
- 补齐单元测试(往返/流水线/超长/Marshal/RawHeader)、examples/frame 例程与 README
2026-09-20 12:20:51 +08:00

1.7 KiB

frame

应用层帧协议:头 8 字节(版本 1 + 命令 1 + 长度 2 + 流 ID 4,小端序)+ 数据, 提供帧与 net.Conn 间的读写封装,配合 JSON 编解码使用。

迁移自 go-hua/common/frame.go,独立成包。

帧格式

+---------+---------+-----------+-----------+----------------+
| ver (1) | cmd (1) | length(2) | sid (4)   | data (length)  |
+---------+---------+-----------+-----------+----------------+
  小端序,length 最大 65535

用法

import (
    "net"

    "git.zeroonesoft.cn/golib/zogo/frame"
)

// 组帧:版本 + 命令字 + 流 ID,数据可 Marshal 任意 JSON 值
f := frame.NewFrame(frame.FrameVersion, 0x10, 42)
f.Marshal(map[string]any{"msg": "hello"})

// 连接上写帧 / 读帧(阻塞直到完整帧)
frame.WriteFrame(conn, f)
got, err := frame.ReadFrame(conn)
var data map[string]any
got.Unmarshal(&data)

完整可运行例程:examples/frame/main.go

迁移修复(相对 go-hua/common 原实现)

  1. SetData 超长未报错:原实现 fmt.Errorf 结果未 return,超长数据静默截断写入; 现超 65535 字节正确返回错误(有回归测试)。
  2. ReadFrame 短读/吞字节:原实现直接 conn.Read 读头(TCP 分段会错位),且用 一次性 bufio.Reader 读体(缓冲里多读到的后续帧字节随 reader 丢弃)。现统一改用 io.ReadFull 精确读取,连续多帧不丢数据(有回归测试)。

注意

  • 单帧数据上限 65535 字节(length 字段 2 字节),更大 payload 请业务侧分片。
  • ReadFrame/WriteFrame 非并发安全,同一连接的读与写可各由一个 goroutine 持有。