118 lines
3.5 KiB
Go
118 lines
3.5 KiB
Go
package dpack
|
||
|
||
import (
|
||
"bytes"
|
||
"encoding/binary"
|
||
"errors"
|
||
"github.com/aceld/zinx/zlog"
|
||
"github.com/aceld/zinx/zpack"
|
||
"time"
|
||
|
||
"github.com/aceld/zinx/zconf"
|
||
"github.com/aceld/zinx/ziface"
|
||
)
|
||
|
||
// +---------------+---------------+--------------------+----------------+-------------------
|
||
// | 开始标志 | type | 秒时间戳 | 长度 | 消息体
|
||
// | 0xffff(2byte) | uint8(1byte) | uint32(4byte) | uint16(2byte) | bytes(N byte)
|
||
// +---------------+---------------+--------------------+----------------+-------------------
|
||
|
||
var defaultHeaderLen uint32 = 9
|
||
|
||
type DataPack struct{}
|
||
|
||
// NewDataPack initializes a packing and unpacking instance
|
||
// (封包拆包实例初始化方法)
|
||
func NewDataPack() ziface.IDataPack {
|
||
return &DataPack{}
|
||
}
|
||
|
||
// GetHeadLen returns the length of the message header
|
||
// (获取包头长度方法)
|
||
func (dp *DataPack) GetHeadLen() uint32 {
|
||
//ID uint32(4 bytes) + DataLen uint32(4 bytes)
|
||
return defaultHeaderLen
|
||
}
|
||
|
||
// Pack packs the message (compresses the data)
|
||
// (封包方法,压缩数据)
|
||
func (dp *DataPack) Pack(msg ziface.IMessage) ([]byte, error) {
|
||
zlog.Ins().InfoF("my pack: %v", msg)
|
||
// Create a buffer to store the bytes
|
||
// (创建一个存放bytes字节的缓冲)
|
||
dataBuff := bytes.NewBuffer([]byte{})
|
||
|
||
// Write the oxffff
|
||
if err := binary.Write(dataBuff, binary.BigEndian, uint16(0xffff)); err != nil {
|
||
return nil, err
|
||
}
|
||
//Write the type
|
||
if err := binary.Write(dataBuff, binary.BigEndian, uint8(msg.GetMsgID())); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
//Write the timestamp
|
||
if err := binary.Write(dataBuff, binary.BigEndian, uint32(time.Now().Unix())); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
//Write the length
|
||
if err := binary.Write(dataBuff, binary.BigEndian, uint16(msg.GetDataLen())); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// Write the data
|
||
if err := binary.Write(dataBuff, binary.BigEndian, msg.GetData()); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return dataBuff.Bytes(), nil
|
||
}
|
||
|
||
// Unpack unpacks the message (decompresses the data)
|
||
// (拆包方法,解压数据)
|
||
func (dp *DataPack) Unpack(binaryData []byte) (ziface.IMessage, error) {
|
||
// Create an ioReader for the input binary data
|
||
dataBuff := bytes.NewReader(binaryData)
|
||
|
||
// Only unpack the header information to obtain the data length and message ID
|
||
// (只解压head的信息,得到dataLen和msgID)
|
||
msg := &zpack.Message{}
|
||
|
||
// Read the startSign
|
||
var startSign uint16
|
||
if err := binary.Read(dataBuff, binary.BigEndian, &startSign); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// Read the msgID
|
||
var msgType uint
|
||
if err := binary.Read(dataBuff, binary.BigEndian, &msgType); err != nil {
|
||
return nil, err
|
||
}
|
||
msg.ID = uint32(msgType)
|
||
|
||
// read timeStamp
|
||
var timeStamp uint32
|
||
if err := binary.Read(dataBuff, binary.BigEndian, &timeStamp); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// Read the data length
|
||
var length uint16
|
||
if err := binary.Read(dataBuff, binary.BigEndian, &length); err != nil {
|
||
return nil, err
|
||
}
|
||
msg.DataLen = uint32(length)
|
||
|
||
// Check whether the data length exceeds the maximum allowed packet size
|
||
// (判断dataLen的长度是否超出我们允许的最大包长度)
|
||
if zconf.GlobalObject.MaxPacketSize > 0 && msg.GetDataLen() > zconf.GlobalObject.MaxPacketSize {
|
||
return nil, errors.New("too large msg data received")
|
||
}
|
||
|
||
// Only the header data needs to be unpacked, and then another data read is performed from the connection based on the header length
|
||
// (这里只需要把head的数据拆包出来就可以了,然后再通过head的长度,再从conn读取一次数据)
|
||
return msg, nil
|
||
}
|