2025-06-23 10:15:22 +08:00
|
|
|
package codec
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/binary"
|
|
|
|
|
"errors"
|
|
|
|
|
"io"
|
|
|
|
|
|
|
|
|
|
"github.com/panjf2000/gnet/v2"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var ErrIncompletePacket = errors.New("incomplete packet")
|
|
|
|
|
|
2025-11-03 05:46:13 +08:00
|
|
|
const maxBodyLen = 10 * 1024 // 业务最大包体长度,按需调整
|
2025-06-23 10:15:22 +08:00
|
|
|
// TomeeSocketCodec 协议格式:
|
|
|
|
|
//
|
|
|
|
|
// * 0 4
|
|
|
|
|
// * +-----------+
|
|
|
|
|
// * | body len |
|
|
|
|
|
// * +-----------+
|
|
|
|
|
// * | |
|
|
|
|
|
// * + +
|
|
|
|
|
// * | body bytes|
|
|
|
|
|
// * + +
|
|
|
|
|
// * | ... ... |
|
|
|
|
|
// * +-----------+
|
|
|
|
|
type TomeeSocketCodec struct{}
|
|
|
|
|
|
|
|
|
|
var _ SocketCodec = (*TomeeSocketCodec)(nil)
|
|
|
|
|
|
|
|
|
|
func NewTomeeSocketCodec() *TomeeSocketCodec {
|
|
|
|
|
return &TomeeSocketCodec{}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (codec TomeeSocketCodec) Encode(buf []byte) ([]byte, error) {
|
|
|
|
|
bodyLen := len(buf)
|
|
|
|
|
data := make([]byte, 4+bodyLen)
|
|
|
|
|
|
|
|
|
|
// 写入4字节的包长度
|
|
|
|
|
binary.BigEndian.PutUint32(data[:4], uint32(bodyLen))
|
|
|
|
|
// 写入包体
|
|
|
|
|
copy(data[4:], buf)
|
|
|
|
|
|
|
|
|
|
return data, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (codec TomeeSocketCodec) Decode(c gnet.Conn) ([]byte, error) {
|
|
|
|
|
|
2025-10-17 10:47:17 +08:00
|
|
|
// handle(c)
|
|
|
|
|
// 先读取4字节的包长度
|
2025-06-23 10:15:22 +08:00
|
|
|
lenBuf, err := c.Peek(4)
|
2025-10-19 02:08:27 +08:00
|
|
|
|
2025-06-23 10:15:22 +08:00
|
|
|
if err != nil {
|
|
|
|
|
if errors.Is(err, io.ErrShortBuffer) {
|
|
|
|
|
return nil, ErrIncompletePacket
|
|
|
|
|
}
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bodyLen := binary.BigEndian.Uint32(lenBuf)
|
2025-10-28 22:08:27 +08:00
|
|
|
|
2025-10-16 23:43:20 +00:00
|
|
|
if bodyLen > maxBodyLen {
|
|
|
|
|
return nil, errors.New("packet body exceeds max length")
|
|
|
|
|
}
|
2025-06-23 10:15:22 +08:00
|
|
|
|
2025-11-01 14:31:19 +08:00
|
|
|
if c.InboundBuffered() < int(bodyLen) {
|
|
|
|
|
return nil, ErrIncompletePacket
|
2025-06-23 10:15:22 +08:00
|
|
|
}
|
2025-10-17 10:47:17 +08:00
|
|
|
// 提取包体
|
2025-11-03 05:46:13 +08:00
|
|
|
body, err := c.Next(int(bodyLen))
|
2025-06-23 10:15:22 +08:00
|
|
|
|
2025-11-03 05:46:13 +08:00
|
|
|
return body, err
|
2025-06-23 10:15:22 +08:00
|
|
|
}
|