go_dreamfactory/lego/sys/proto/defmessage.go
2022-06-07 20:18:22 +08:00

219 lines
6.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package proto
import (
"bufio"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"reflect"
"go_dreamfactory/lego/sys/rpc"
"github.com/golang/protobuf/proto"
)
//默认消息体
type DefMessage struct {
ComId uint16 //主Id
MsgId uint16 //次Id
MsgLen uint32 //消息体长度
Buffer []byte //消息体
}
func (this *DefMessage) GetComId() uint16 {
return this.ComId
}
func (this *DefMessage) GetMsgId() uint16 {
return this.MsgId
}
func (this *DefMessage) GetMsgLen() uint32 {
return this.MsgLen
}
func (this *DefMessage) GetBuffer() []byte {
return this.Buffer
}
func (this *DefMessage) ToStriing() string {
return fmt.Sprintf("ComId%d MsgId:%d MsgLen:%d", this.ComId, this.MsgId, this.MsgLen)
}
//默认消息工厂
type DefMessageFactory struct {
msgProtoType ProtoType //消息体类型
isUseBigEndian bool //消息传输码
msgheadsize uint32 //消息头大小
msgmaxleng uint32 //消息体最大长度
}
func (this *DefMessageFactory) SetMessageConfig(MsgProtoType ProtoType, IsUseBigEndian bool) {
this.msgProtoType = MsgProtoType
this.isUseBigEndian = IsUseBigEndian
this.msgheadsize = 8
this.msgmaxleng = 1024 * 1204 * 3
//自己rpc消息解析
rpc.OnRegisterRpcData(&DefMessage{}, this.RpcEncodeMessage, this.RpcDecodeMessage)
}
func (this *DefMessageFactory) DecodeMessageBybufio(r *bufio.Reader) (message IMessage, err error) {
msg := &DefMessage{}
msg.ComId, err = this.readUInt16(r)
if err != nil {
return msg, err
}
msg.MsgId, err = this.readUInt16(r)
if err != nil {
return msg, err
}
msg.MsgLen, err = this.readUInt32(r)
if err != nil {
return msg, err
}
if msg.MsgLen > this.msgmaxleng {
return nil, fmt.Errorf("DecodeMessageBybufio err msg.MsgLen:%d Super long", msg.MsgLen)
}
msg.Buffer = make([]byte, msg.MsgLen)
_, err = io.ReadFull(r, msg.Buffer)
return msg, err
}
func (this *DefMessageFactory) DecodeMessageBybytes(buffer []byte) (message IMessage, err error) {
if uint32(len(buffer)) >= this.msgheadsize {
msg := &DefMessage{}
if this.isUseBigEndian {
msg.ComId = binary.BigEndian.Uint16(buffer[0:])
msg.MsgId = binary.BigEndian.Uint16(buffer[2:])
msg.MsgLen = binary.BigEndian.Uint32(buffer[4:])
} else {
msg.ComId = binary.LittleEndian.Uint16(buffer[0:])
msg.MsgId = binary.LittleEndian.Uint16(buffer[2:])
msg.MsgLen = binary.LittleEndian.Uint32(buffer[4:])
}
if uint32(len(buffer)) >= msg.MsgLen+this.msgheadsize {
msg.Buffer = buffer[this.msgheadsize : msg.MsgLen+this.msgheadsize]
return msg, nil
} else {
return nil, fmt.Errorf("DecodeMessageBybytes err package:%v msg.MsgLen:%d", buffer, msg.MsgLen)
}
}
return nil, fmt.Errorf("DecodeMessageBybytes err package:%v", buffer)
}
func (this *DefMessageFactory) EncodeToMesage(comId uint16, msgId uint16, msg interface{}) (message IMessage) {
defmessage := &DefMessage{
ComId: uint16(comId),
MsgId: uint16(msgId),
}
if this.msgProtoType == Proto_Buff {
defmessage.Buffer, _ = proto.Marshal(msg.(proto.Message))
} else {
defmessage.Buffer, _ = json.Marshal(msg)
}
defmessage.MsgLen = uint32(len(defmessage.Buffer))
return defmessage
}
func (this *DefMessageFactory) EncodeToByte(message IMessage) (buffer []byte) {
if this.isUseBigEndian {
buffer := []byte{}
_msg := make([]byte, 2)
binary.BigEndian.PutUint16(_msg, message.GetComId())
buffer = append(buffer, _msg...)
_msg = make([]byte, 2)
binary.BigEndian.PutUint16(_msg, message.GetMsgId())
buffer = append(buffer, _msg...)
_msg = make([]byte, 4)
binary.BigEndian.PutUint32(_msg, message.GetMsgLen())
buffer = append(buffer, _msg...)
buffer = append(buffer, message.GetBuffer()...)
return buffer
} else {
buffer := []byte{}
_msg := make([]byte, 2)
binary.LittleEndian.PutUint16(_msg, message.GetComId())
buffer = append(buffer, _msg...)
_msg = make([]byte, 2)
binary.LittleEndian.PutUint16(_msg, message.GetMsgId())
buffer = append(buffer, _msg...)
_msg = make([]byte, 4)
binary.LittleEndian.PutUint32(_msg, message.GetMsgLen())
buffer = append(buffer, _msg...)
buffer = append(buffer, message.GetBuffer()...)
return buffer
}
}
func (this *DefMessageFactory) RpcEncodeMessage(d interface{}) ([]byte, error) {
message := d.(IMessage)
if this.isUseBigEndian {
buffer := []byte{}
_msg := make([]byte, 2)
binary.BigEndian.PutUint16(_msg, message.GetComId())
buffer = append(buffer, _msg...)
_msg = make([]byte, 2)
binary.BigEndian.PutUint16(_msg, message.GetMsgId())
buffer = append(buffer, _msg...)
_msg = make([]byte, 4)
binary.BigEndian.PutUint32(_msg, message.GetMsgLen())
buffer = append(buffer, _msg...)
buffer = append(buffer, message.GetBuffer()...)
return buffer, nil
} else {
buffer := []byte{}
_msg := make([]byte, 2)
binary.LittleEndian.PutUint16(_msg, message.GetComId())
buffer = append(buffer, _msg...)
_msg = make([]byte, 2)
binary.LittleEndian.PutUint16(_msg, message.GetMsgId())
buffer = append(buffer, _msg...)
_msg = make([]byte, 4)
binary.LittleEndian.PutUint32(_msg, message.GetMsgLen())
buffer = append(buffer, _msg...)
buffer = append(buffer, message.GetBuffer()...)
return buffer, nil
}
}
func (this *DefMessageFactory) RpcDecodeMessage(dataType reflect.Type, d []byte) (interface{}, error) {
return this.DecodeMessageBybytes(d)
}
func (this *DefMessageFactory) readByte(r *bufio.Reader) (byte, error) {
buf := make([]byte, 1)
_, err := io.ReadFull(r, buf[:1])
if err != nil {
return 0, err
}
return buf[0], nil
}
func (this *DefMessageFactory) readUInt16(r *bufio.Reader) (uint16, error) {
buf := make([]byte, 2)
_, err := io.ReadFull(r, buf[:2])
if err != nil {
return 0, err
}
if this.isUseBigEndian {
return binary.BigEndian.Uint16(buf[:2]), nil
} else {
return binary.LittleEndian.Uint16(buf[:2]), nil
}
}
func (this *DefMessageFactory) readUInt32(r *bufio.Reader) (uint32, error) {
buf := make([]byte, 4)
_, err := io.ReadFull(r, buf[:4])
if err != nil {
return 0, err
}
if this.isUseBigEndian {
return binary.BigEndian.Uint32(buf[:4]), nil
} else {
return binary.LittleEndian.Uint32(buf[:4]), nil
}
}