All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
feat(socket): 使用bytebufferpool优化内存分配并重构消息处理机制 引入bytebufferpool减少内存分配开销,在ServerEvent.go中修改数据处理逻辑, 将直接的数据拷贝改为使用缓冲池。同时移除原有的消息通道机制,改用lock
95 lines
2.5 KiB
Go
95 lines
2.5 KiB
Go
package common
|
||
|
||
import (
|
||
"bytes"
|
||
"encoding/binary"
|
||
"fmt"
|
||
|
||
"github.com/lunixbochs/struc"
|
||
"github.com/valyala/bytebufferpool"
|
||
)
|
||
|
||
// TomeeHeader 结构体字段定义
|
||
type TomeeHeader struct {
|
||
Len uint32 `json:"len"`
|
||
Version byte `json:"version" struc:"[1]byte"`
|
||
CMD uint32 `json:"cmdId" struc:"uint32"`
|
||
UserID uint32 `json:"userId"`
|
||
//Error uint32 `json:"error" struc:"skip"`
|
||
|
||
Result uint32 `json:"result"`
|
||
Data *bytebufferpool.ByteBuffer `json:"data" struc:"skip"` //组包忽略此字段// struc:"skip"
|
||
Res []byte `struc:"skip"`
|
||
//Return []byte `struc:"skip"` //返回记录
|
||
}
|
||
|
||
func NewTomeeHeader(cmd uint32, userid uint32) *TomeeHeader {
|
||
|
||
return &TomeeHeader{
|
||
CMD: cmd,
|
||
// Len: 0,
|
||
Version: 49,
|
||
Result: 0,
|
||
}
|
||
|
||
}
|
||
|
||
// Pack 组包方法:手动编码字节流,兼容interface{}、nil、多层指针/接口
|
||
func (h *TomeeHeader) Pack(data any) []byte {
|
||
if data == nil {
|
||
return h.packHeaderWithData([]byte{})
|
||
}
|
||
var data1 bytes.Buffer
|
||
err := struc.Pack(&data1, data)
|
||
if err != nil {
|
||
fmt.Println(err)
|
||
}
|
||
|
||
if len(data1.Bytes()) == 0 {
|
||
// fmt.Println("数据为空")
|
||
|
||
}
|
||
//datar = data1.Bytes()
|
||
// 4. 手动打包包头+数据体
|
||
return h.packHeaderWithData(data1.Bytes())
|
||
}
|
||
|
||
// packHeaderWithData 手动编码包头和数据体(静态指定偏移量,无自增变量)
|
||
// 包头固定结构(大端序):
|
||
// - 0-3 字节:Len (uint32)
|
||
// - 4 字节:Version (byte)
|
||
// - 5-8 字节:CMD (uint32,从uint64截断)
|
||
// - 9-12 字节:UserID (uint32)
|
||
// - 13-16 字节:Result (uint32)
|
||
// 17字节后:数据体
|
||
func (h *TomeeHeader) packHeaderWithData(data []byte) []byte {
|
||
// 计算总长度:包头17字节 + 数据体长度
|
||
dataLen := len(data)
|
||
h.Len = uint32(17 + dataLen)
|
||
|
||
// 预分配切片(总长度 = 包头 + 数据体),避免多次扩容
|
||
buf := make([]byte, h.Len)
|
||
|
||
// 1. 写入Len(固定偏移:0-3 字节,大端序)
|
||
binary.BigEndian.PutUint32(buf[0:4], h.Len)
|
||
|
||
// 2. 写入Version(固定偏移:4 字节)
|
||
buf[4] = h.Version
|
||
|
||
// 3. 写入CMD(固定偏移:5-8 字节,大端序)
|
||
binary.BigEndian.PutUint32(buf[5:9], uint32(h.CMD))
|
||
|
||
// 4. 写入UserID(固定偏移:9-12 字节,大端序)
|
||
binary.BigEndian.PutUint32(buf[9:13], h.UserID)
|
||
|
||
// 5. 写入Result(固定偏移:13-16 字节,大端序)
|
||
binary.BigEndian.PutUint32(buf[13:17], h.Result)
|
||
|
||
// 6. 写入数据体(固定起始偏移:17 字节,若有数据则拷贝)
|
||
if dataLen > 0 {
|
||
copy(buf[17:], data)
|
||
}
|
||
|
||
return buf
|
||
}
|