init: 自 zomaintain/backend/zonat 平移独立成库; module path 改为 git.zeroonesoft.cn/golib/zonat; 内部 import 同步重写

This commit is contained in:
w11
2026-09-19 18:55:43 +08:00
commit 984041f1a0
20 changed files with 2427 additions and 0 deletions
+149
View File
@@ -0,0 +1,149 @@
// frame.go 帧协议,wire format 与 zonat 桥接帧完全一致
// (ver(1) + cmd(1) + length(2, LE) + sid(4, LE) + data)。
// 本文件取自 zonat client/internal/frame 的本地修复副本,仅裁掉未用方法。
package agent
import (
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io"
"net"
)
const FrameVersion byte = 1
// 帧头部
const (
sizeOfVer = 1
sizeOfCmd = 1
sizeOfLength = 2
sizeOfSid = 4
headerSize = sizeOfVer + sizeOfCmd + sizeOfSid + sizeOfLength
)
const (
frameBufSize = 0x10000
)
type Frame struct {
ver byte
cmd byte
sid uint32
data []byte
}
func NewFrame(version byte, cmd byte, sid uint32) Frame {
return Frame{ver: version, cmd: cmd, sid: sid}
}
// ReadFrame 读取一帧。头部与数据均用 ReadFull,防止单次 Read 短读导致解析错乱,
// 也不会把后续帧的数据读进缓冲丢弃。
func ReadFrame(conn net.Conn) (Frame, error) {
f := NewFrame(0, 0, 0)
hdr := RawHeader{}
if _, err := io.ReadFull(conn, hdr[:]); err != nil {
return f, err
}
f.ver = hdr.Version()
f.cmd = hdr.Cmd()
f.sid = hdr.StreamID()
length := int(hdr.Length())
if length == 0 {
return f, nil
}
data := make([]byte, length)
if _, err := io.ReadFull(conn, data); err != nil {
return f, err
}
f.data = data
return f, nil
}
func WriteFrame(conn net.Conn, frame Frame) error {
hdr := RawHeader{}
hdr[0] = frame.ver
hdr[1] = frame.cmd
binary.LittleEndian.PutUint16(hdr[2:], uint16(len(frame.data)))
binary.LittleEndian.PutUint32(hdr[4:], frame.sid)
buf := hdr.Bytes()
buf = append(buf, frame.data...)
_, err := conn.Write(buf)
return err
}
func (f *Frame) Version() byte {
return f.ver
}
func (f *Frame) Cmd() byte {
return f.cmd
}
func (f *Frame) Length() uint16 {
return uint16(len(f.data))
}
func (f *Frame) Data() []byte {
return f.data
}
func (f *Frame) StreamID() uint32 {
return f.sid
}
func (f *Frame) SetData(data []byte) error {
if len(data) > frameBufSize-1 {
return fmt.Errorf("超出最大长度:%d", frameBufSize-1)
}
f.data = data
return nil
}
func (f *Frame) Marshal(v any) error {
buf, err := json.Marshal(v)
if err != nil {
return err
}
return f.SetData(buf)
}
func (f *Frame) Unmarshal(v any) error {
if len(f.data) == 0 {
return errors.New("没有数据")
}
return json.Unmarshal(f.data, v)
}
func (f *Frame) String() string {
return fmt.Sprintf("Version:%d Cmd:%d StreamID:%d Length:%d",
f.Version(), f.Cmd(), f.StreamID(), f.Length())
}
type RawHeader [headerSize]byte
func (h RawHeader) Version() byte {
return h[0]
}
func (h RawHeader) Cmd() byte {
return h[1]
}
func (h RawHeader) Length() uint16 {
return binary.LittleEndian.Uint16(h[2:])
}
func (h RawHeader) StreamID() uint32 {
return binary.LittleEndian.Uint32(h[4:])
}
func (h RawHeader) Bytes() []byte {
buf := make([]byte, headerSize)
copy(buf, h[:])
return buf
}